![](/img/trans.png)
[英]Django rest framework- writable(create,update) double nested serializer
[英]Django REST Framework- how can I create or update a foreign key object when POSTing parent
我目前正在为作业计划系统开发 API 视图。 每个Job
都有一个JobPlan
(有开始和结束日期),每个JobPlan
可能有多个JobPlanManagers
,分配给用户来管理所述Job
。 用户一可能负责一个月,用户二可能与用户 1 重叠,但将工作延长几周。 因此,当用户 2 发布他们的新JobPlanManager
实例时,他们需要创建一个新的 JobPlan(如果尚不存在计划)或更新现有的JobPlan
,以适当地延长开始和结束时间。 用户的 POST 数据将包括他们的用户 ID、作业 ID 以及开始和结束日期,例如:
{
"manager": (User ID),
"job_plan": {
"id": null,
"job": {
"id": (existing Job ID)
},
"start": "2018-02-01",
"end": "2018-02-28"
}
}
此外,我希望此 POST 调用的返回包含 JobPlan 和 Job 的所有字段,嵌套:例如:
{
"id": (created JobPlanManager instance ID)
"manager": (User ID),
"job_plan": {
"id": (New or existing JobPlan ID)
"job": {
"id": (Existing Job ID),
"name": "Existing Job Name"
}
"start": "2018-01-02",
"end": "2018-02-28"
}
}
我的模型看起来像:
class Job(models.Model)
name = models.CharField()
class JobPlan(models.Model):
job = models.ForeignKey(Job, unique=True)
start = models.DateField()
end = models.DateField()
class JobPlanManager(models.Model):
job_plan = models.ForeignKey(JobPlan)
manager = models.ForeignKey(User)
is_open = models.Boolean(default=False)
delta = models.IntegerField()
对于我的序列化程序,我在单独的调用中执行此操作(例如-首先创建/更新JobPlan
,然后将返回的 id 与用户 ID 一起传递以创建我的新JobPlanManager
),它们看起来像这样:
class JobSerializer(serializers.ModelSerializer):
class Meta:
model = Job
fields = ('id', 'name',)
read_only_fields('id')
class JobPlanSerializer(serializers.ModelSerializer):
job = JobSerializer(many=False)
class Meta:
model = JobPlan
fields = ('id', 'job', 'start', 'end',)
read_only_fields('id')
def create(self, validated_data):
i_job = validated_data.get('job', None)
start = validated_data.get('start', None)
end = validated_data.get('end', None)
if JobPlan.objects.filter(job=i_job).exists():
jobplan = JobPlan.objects.get(job=i_job)
jobplan.start = min(jobplan.start, start)
jobplan.end = max(jobplan.end, end)
jobplan.save()
else:
jobplan = JobPlan.objects.create(job=i_job, start=start, end=end)
return jobplan
class JobPlanManagerSerializer(serializers.ModelSerializer):
job_plan = JobPlanSerializer(many=False)
class Meta:
model = JobPlanManager
fields = ('job_plan', 'manager', 'is_open', 'delta',)
read_only_fields('id')
有没有人知道一种方法,我可以在一次调用中完成这一切(如上所述)并从上述调用中获得上述回报?
我用这个技巧让它工作:
class JobPlanSerializer(serializers.ModelSerializer):
job = PrimaryKeyRelatedField()
class Meta:
...
def create(self, validated_data):
...
def to_representation(self, instance):
ret = super().to_representation(instance)
ret['job'] = JobSerializer(context=self.context).to_representation(instance.job)
return ret
发布数据时只需发送"job": (Existing Job ID)
而不是"job": {"id": (existing Job ID)}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.