Django休息视图包含响应中的一对多相关对象

时间:2017-07-14 15:54:08

标签: django django-views django-rest-framework django-serializer

我有两个模型如下:

class Task(models.Model):
    what_task = models.CharField(max_length=100, )
    how_often = models.CharField(max_length=50, )
    how_important = models.CharField(max_length=50, )
 )

    #This helps to print in admin interface
    def __str__(self):
        return u"%s" % (self.what_task)


class Step(models.Model):
    task = models.ForeignKey(Task, on_delete=models.CASCADE, )
    what_step = models.CharField(max_length=50, blank=True, )

    #This helps to print in admin interface
    def __str__(self):
        return u"%s" % (self.what_step)

我为他们写了序列化器:

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = '__all__'
        depth = 1


class StepSerializer(serializers.ModelSerializer):
    class Meta:
        model = Step
        fields = '__all__'

我的一个观点是:

@api_view(['GET', 'POST'])
def task_list(request):
    """
    List all tasks, or create a new task.
    """
    if request.method == 'GET':
        tasks = Task.objects.all()
        serializer = TaskSerializer(tasks, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = TaskSerializer(data=request.DATA)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(
                serializer.errors, status=status.HTTP_400_BAD_REQUEST)

这给了我以下数据:

[
  {
    id: 1,
    what_task: "Sample task one",
    how_often: "Daily",
    how_important: "Extremely important",

  }
]

但是我想在检索像bellow:

这样的任务时包含相关的Steps
[
  {
    id: 1,
    what_task: "Sample task one",
    how_often: "Daily",
    how_important: "Extremely important",
    steps:[]
  }
]

此外,当用户创建Task时,他也可以同时创建Steps,我可以非常期待上面传入的JSON。 我怎样才能做到这一点?我是在串行器中还是在视图中处理它?<​​/ p>

1 个答案:

答案 0 :(得分:1)

您必须覆盖TaskSerializer创建任务和步骤的方式。

class StepSerializer(serializers.ModelSerializer):
    class Meta:
        model = Step
        fields = '__all__'


class TaskSerializer(serializers.ModelSerializer):
    steps = StepSerializer(many=True)

    class Meta:
        model = Task
        fields = '__all__'
        depth = 1

    def create(self, validated_data):
        steps_data = validated_data.pop('steps')
        task = Task.objects.create(**validated_data)
        for step_data in steps_data:
            Step.objects.create(task=task, **step_data)
        return task

您可以在文档中找到详细信息:writable-nested-serializers

要在创建新任务时创建步骤,您可以这样做:

{
    "what_task": "Sample task one",
    "how_often": "Daily",
    "how_important": "Extremely important",
    "steps": [
        {"what_step": 10},
        {"what_step": 123}
    ]
}