Python DRF-使用多个外键序列化模型

Python DRF-使用多个外键序列化模型,python,django,django-rest-framework,relationship,Python,Django,Django Rest Framework,Relationship,我正在Django中开发一个CRUDAPI,我需要序列化一个在两个表中包含外键的模型。该模型在两个一对多关系上是“多”的,我真的看不到在这个模型中指定关系的任何其他方式(我对python和Django是新手,我使用Django Rest框架来创建API) 因此,我有两个问题: 1-在我的模型中有多个外键是一个好主意,还是我应该以其他方式折射我的关系? 2-如果在一个模型中有多个外键是可以的,那么如何序列化模型以返回正确的JSON? 我的模型是这样的(还有几个字段): 交付记录引用了为其进行交付的

我正在Django中开发一个CRUDAPI,我需要序列化一个在两个表中包含外键的模型。该模型在两个一对多关系上是“多”的,我真的看不到在这个模型中指定关系的任何其他方式(我对python和Django是新手,我使用Django Rest框架来创建API)

因此,我有两个问题:

1-
在我的模型中有多个外键是一个好主意,还是我应该以其他方式折射我的关系?

2-
如果在一个模型中有多个外键是可以的,那么如何序列化模型以返回正确的JSON?

我的模型是这样的(还有几个字段):

交付记录引用了为其进行交付的活动以及为该交付选择的数据源

必须以以下格式返回数据:

{
    campaign_id: 001,
    datasource_id: 002,
    datasource_name: "Data Source Name",
    campaign_name: "Campaign Name"
    setup_date:"<Setup Date>",
    delivery_history:[{
        delivery_reference_id:DL_001,
        sender : "abc@xyz.com",
        subject : "Subject",
        sent_on : "<Date>"
    },
    {
        delivery_reference_id:DL_002,
        sender : "abc@xyz.com",
        subject : "Subject",
        sent_on : "<Date>"
    },
    {
        delivery_reference_id:DL_003,
        sender : "abc@xyz.com",
        subject : "Subject",
        sent_on : "<Date>"
    }
    ....
    ]
}
{
活动编号:001,
数据源_id:002,
数据源名称:“数据源名称”,
活动名称:“活动名称”
安装日期:“,
交付历史记录:[{
交付参考编号:DL\U 001,
发件人:“abc@xyz.com",
主题:“主题”,
发送至:“
},
{
交付参考编号:DL\U 002,
发件人:“abc@xyz.com",
主题:“主题”,
发送至:“
},
{
交付参考号:DL\U 003,
发件人:“abc@xyz.com",
主题:“主题”,
发送至:“
}
....
]
}
datasource\u id
campaign\u id
字段是django在创建记录时为记录提供的默认id,
delivery\u reference\u id
是创建交付记录时分配的自定义id

我希望我已经把事情说清楚了。但是,如果有什么不清楚的地方,请询问。

1)如何根据自己的逻辑对模型进行FK是您的意见,但在本例中,这是我的方法

2) 以下是答案:

默认情况下,必须为每个FK命名与主模型相关的\u名称

models.py serialiers.py viwes.py
通常将
ForeignKey
字段命名为:

class CampaignDelivery(models.Model):
    campaign = models.ForeignKey('Campaign')
字段
活动\u id
是自动添加的,是对存储活动id的表字段的引用。我经常是有用的。所以
CampaignDelivery.campaign
返回django对象,而
CampaignDelivery.campaign\u id
返回引用活动的id

在一个模型中使用多个外键没有什么错,但我不确定您希望在这里实现什么。我认为您需要获取
活动
数据及其交付历史记录。 您提供的响应示例在这方面不是很好,因为它意味着可以将一次交付分配给多个活动(这不是真的,因为您有
ForeignKey
)。您可以这样完成此任务:

from rest_framework import serializers

class CampaignDeliverySerializer(serializers.ModelSerializer):

    class Meta:
        model = CampaignDelivery
        fields = ('date_sent', 'datasource_id', 'delivery_reference_id', 'datasource__datasource_name', ...)

class CampaignSerializer(serialziers.ModelSerializer):
    delivery_history = CampaignDeliverySerializer(
                           source='campaigndeliveries_set', 
                           many=True
                       )

    class Meta:
        model = Campaign
        fields = ('id', 'name', 'sender', 'subject', 'delivery_history', ...)
答复示例:

{
    'campaign': {
        'id': 123,
        'name': 'Best campaign name evar',
        'sender': 'foo@bar.com',
        'subject': 'Campaign subject',
        'delivery_history': [
            {
                'date_sent': '2017-02-22',
                'datasource_id': 321,
                'delivery_reference_id': 'DL_001',
                'datasource__datasource_name': 'Datasource name'
            },
            ...
        ]
    }
}

试试这个:你查询什么来获取数据。您可以分享填充交付历史的模型吗?您使用什么框架来进行DRF?@BipulJain:我正在使用以下模型填充交付历史:
{“活动id”:1,“数据源id”:1,“交付参考id”:“DL_01”,“发送日期”:“2017-02-17T00:05:00Z”}
并按如下方式查询数据:
/api/campaints/:campaign id/history/:delivery\u reference\u id
@marin:DRF=Django Rest Framework?还没完全明白你的问题吗?不!您已经使模型和序列化程序与它们应该达到的完全相反!您现在可以用另一种方式思考。但我的数据源并不局限于单个活动交付,单个数据源可以用于多个活动交付,单个活动也可以使用不同的数据源多次交付。因此,我需要表示这样一个事实,即数据源和活动组合已交付并记录到活动交付表中。交付可以包含活动和数据源的任意组合。这就是我有两个外键的原因。通过示例响应更合理。谢谢:)
qv = CampaignDeliveries.objects.all()
serializer = CampaignDeliveriesSerilaizer(qv)
print (serializer.data)
class CampaignDelivery(models.Model):
    campaign = models.ForeignKey('Campaign')
from rest_framework import serializers

class CampaignDeliverySerializer(serializers.ModelSerializer):

    class Meta:
        model = CampaignDelivery
        fields = ('date_sent', 'datasource_id', 'delivery_reference_id', 'datasource__datasource_name', ...)

class CampaignSerializer(serialziers.ModelSerializer):
    delivery_history = CampaignDeliverySerializer(
                           source='campaigndeliveries_set', 
                           many=True
                       )

    class Meta:
        model = Campaign
        fields = ('id', 'name', 'sender', 'subject', 'delivery_history', ...)
{
    'campaign': {
        'id': 123,
        'name': 'Best campaign name evar',
        'sender': 'foo@bar.com',
        'subject': 'Campaign subject',
        'delivery_history': [
            {
                'date_sent': '2017-02-22',
                'datasource_id': 321,
                'delivery_reference_id': 'DL_001',
                'datasource__datasource_name': 'Datasource name'
            },
            ...
        ]
    }
}