我目前正在工作计划系统的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)}

关于python - Django REST Framework-POST父级时如何创建或更新外键对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48723948/

10-09 14:34