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