DRF - 序列化具有多个外键的模型
DRF - Serializing a model with multiple foreign Keys
我正在 Django 中处理 CRUD API,我需要序列化一个模型,该模型在两个表中都有外键。该模型在两个一对多关系的 'many' 端,我真的没有看到在这个模型中指定关系的任何其他方式(我是 python 和 Django 的新手,我是使用 Django-Rest-Framework 创建 API)
那么,我有两个问题:
1 - Is it a good Idea to have multiple foreign keys in my model or I should refractor my relationships some other way?
2 - If it is fine to have multiple foreign keys in a single model, how do I serialize the model to return the proper JSON?
我的模型是这样的(多了几个字段):
class DataSource(models.Model):
datasource_name = models.CharField(max_length=50, unique=True)
datasource_description = models.CharField(max_length=100)
...
class Campaign(models.Model):
name = models.CharField(max_length=200)
subject = models.CharField(max_length=200)
sender = models.EmailField(max_length=200)
...
class CampaignDeliveries(models.Model):
campaign_id = models.ForeignKey(Campaign)
datasource_id = models.ForeignKey(DataSource)
delivery_reference_id = models.CharField(max_length=200, primary_key=True)
date_sent = models.DateTimeField()
交付记录引用了进行交付的活动以及为该交付选择的数据源。
必须以如下格式返回数据:
{
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>"
}
....
]
}
datasource_id
和 campaign_id
字段是 django 在创建记录时给记录的默认 ID,delivery_reference_id
是在创建交付记录时分配的自定义 ID .
希望我已经说清楚了。不过有什么不明白的请追问。
1) 你认为如何根据自己的逻辑对模型进行 FK,但在这个例子中,这是我的方式。
2) 这是答案:
默认情况下,您必须为主模型的每个 FK 命名 related_name。
models.py
class CampaignDeliveries(models.Model):
delivery_reference_id = models.CharField(max_length=200, primary_key=True)
date_sent = models.DateTimeField()
class DataSource(models.Model):
datasource_name = models.CharField(max_length=50, unique=True)
datasource_description = models.CharField(max_length=100)
campain_id = models.ForeignKey(CampaignDeliveries, related_name='data_source')
class Campaign(models.Model):
name = models.CharField(max_length=200)
subject = models.CharField(max_length=200)
sender = models.EmailField(max_length=200)
campain_id = models.ForeignKey(CampaignDeliveries, related_name='campaign_source')
serialiers.py
class DataSourceSerilaizer(serializers.ModelSerializer)
class Meta:
model = DataSource
fileds = '__all__'
class CampaignSerilaizer(serializers.ModelSerializer)
class Meta:
model = Campaign
fileds = '__all__'
class CampaignDeliveriesSerilaizer(serializers.ModelSerializer):
campaign_source = CampaignSerilaizer(many=True)
data_source = DataSourceSerilaizer(many=True)
class Meta:
model = CampaignDeliveries
fileds = '__all__'
viwes.py
qv = CampaignDeliveries.objects.all()
serializer = CampaignDeliveriesSerilaizer(qv)
print (serializer.data)
通常你会这样命名你的 ForeignKey
字段:
class CampaignDelivery(models.Model):
campaign = models.ForeignKey('Campaign')
字段 campaign_id
是自动添加的,是对存储活动 ID 的 table 字段的引用。我可以经常派上用场。所以 CampaignDelivery.campaign
returns django 对象和 CampaignDelivery.campaign_id
returns 引用活动的 ID。
在一个模型中有多个外键没有错,但我不确定你想在这里完成什么。我认为您需要获取 Campaign
数据及其交付历史记录。
您提供的响应示例对此并不是很好,因为它暗示一次交付可以分配给多个活动(这不是真的,因为您有 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'
},
...
]
}
}
我正在 Django 中处理 CRUD API,我需要序列化一个模型,该模型在两个表中都有外键。该模型在两个一对多关系的 'many' 端,我真的没有看到在这个模型中指定关系的任何其他方式(我是 python 和 Django 的新手,我是使用 Django-Rest-Framework 创建 API)
那么,我有两个问题:
1 - Is it a good Idea to have multiple foreign keys in my model or I should refractor my relationships some other way?
2 - If it is fine to have multiple foreign keys in a single model, how do I serialize the model to return the proper JSON?
我的模型是这样的(多了几个字段):
class DataSource(models.Model):
datasource_name = models.CharField(max_length=50, unique=True)
datasource_description = models.CharField(max_length=100)
...
class Campaign(models.Model):
name = models.CharField(max_length=200)
subject = models.CharField(max_length=200)
sender = models.EmailField(max_length=200)
...
class CampaignDeliveries(models.Model):
campaign_id = models.ForeignKey(Campaign)
datasource_id = models.ForeignKey(DataSource)
delivery_reference_id = models.CharField(max_length=200, primary_key=True)
date_sent = models.DateTimeField()
交付记录引用了进行交付的活动以及为该交付选择的数据源。
必须以如下格式返回数据:
{
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>"
}
....
]
}
datasource_id
和 campaign_id
字段是 django 在创建记录时给记录的默认 ID,delivery_reference_id
是在创建交付记录时分配的自定义 ID .
希望我已经说清楚了。不过有什么不明白的请追问。
1) 你认为如何根据自己的逻辑对模型进行 FK,但在这个例子中,这是我的方式。
2) 这是答案:
默认情况下,您必须为主模型的每个 FK 命名 related_name。
models.py
class CampaignDeliveries(models.Model):
delivery_reference_id = models.CharField(max_length=200, primary_key=True)
date_sent = models.DateTimeField()
class DataSource(models.Model):
datasource_name = models.CharField(max_length=50, unique=True)
datasource_description = models.CharField(max_length=100)
campain_id = models.ForeignKey(CampaignDeliveries, related_name='data_source')
class Campaign(models.Model):
name = models.CharField(max_length=200)
subject = models.CharField(max_length=200)
sender = models.EmailField(max_length=200)
campain_id = models.ForeignKey(CampaignDeliveries, related_name='campaign_source')
serialiers.py
class DataSourceSerilaizer(serializers.ModelSerializer)
class Meta:
model = DataSource
fileds = '__all__'
class CampaignSerilaizer(serializers.ModelSerializer)
class Meta:
model = Campaign
fileds = '__all__'
class CampaignDeliveriesSerilaizer(serializers.ModelSerializer):
campaign_source = CampaignSerilaizer(many=True)
data_source = DataSourceSerilaizer(many=True)
class Meta:
model = CampaignDeliveries
fileds = '__all__'
viwes.py
qv = CampaignDeliveries.objects.all()
serializer = CampaignDeliveriesSerilaizer(qv)
print (serializer.data)
通常你会这样命名你的 ForeignKey
字段:
class CampaignDelivery(models.Model):
campaign = models.ForeignKey('Campaign')
字段 campaign_id
是自动添加的,是对存储活动 ID 的 table 字段的引用。我可以经常派上用场。所以 CampaignDelivery.campaign
returns django 对象和 CampaignDelivery.campaign_id
returns 引用活动的 ID。
在一个模型中有多个外键没有错,但我不确定你想在这里完成什么。我认为您需要获取 Campaign
数据及其交付历史记录。
您提供的响应示例对此并不是很好,因为它暗示一次交付可以分配给多个活动(这不是真的,因为您有 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'
},
...
]
}
}