Django REST Framework嵌套序列化器FK创建

时间:2015-08-17 04:13:23

标签: python json django django-rest-framework

使用DRF嵌套序列化程序创建一堆相关模型时遇到了麻烦。 他们未能对外键进行验证。

模型

class Employee(models.Model):
    user = models.OneToOneField(User)  # Django user
    ...

class Task(models.Model):
    author = models.ForeignKey(Employee, related_name='tasks')
    title = models.CharField(max_length=64)
    ...

class EmployeeTarget(models.Model):
    employee = models.ForeignKey(Employee, null=False)
    task = models.ForeignKey(Task, null=False, related_name='employee_targets')
    ...

目标

基本上我已经创建了Employees,我想在一个请求中创建一个Task和相关的EmployeeTarget,将请求用户作为author。 JSON请求示例:

{
    "title": "Lorem Ipsum",
    "employee_targets": [
         { "employee": 10 },
         { "employee": 11 }]
}
/* or */
{
    "title": "Lorem Ipsum",
    "employee_targets": [10,11]
}

串行器

class EmployeeSerializer(serializers.ModelSerializer):
    name = serializers.CharField(source="user.get_full_name", read_only=True)
    email = serializers.CharField(source="user.email", read_only=True)

    class Meta:
        model = Employee

class EmployeeTargetSerializer(serializers.ModelSerializer):
    employee = EmployeeSerializer()

    class Meta:
        model = EmployeeTarget

class TaskSerializer(base.ModelSerializer):
    employee_targets = EmployeeTargetSerializer(many=True, required=False)

    class Meta:
        model = Task

    def create(self, validated_data):
        employee_target_data = validated_data.pop('employee_targets')
        task = Task.objects.create(**validated_data)
        EmployeeTarget.objects.create(task=task, **employee_target_data)
        return task

视图集

class TaskViewSet(ModelViewSet):

    serializer_class = TaskSerializer

    def get_queryset(self):
        request_employee = self.request.user.employee
        return Task.objects.filter(Q(author=request_employee) |
                                   Q(employee_targets__employee=request_employee))

    def perform_create(self, serializer):
        serializer.save(author=self.request.user.employee)

结果

我收到400 BAD REQUEST并出现以下错误:

{
  "employee_targets": [
    {
      "employee": {
        "non_field_errors": ["Invalid data. Expected a dictionary, but got int."]
      },
      "task": ["This field is required."]
    }
  ],
  "author": ["This field is required."]
}

预计会出现employee错误,但我还没想出如何仅使用ID创建它们。

这里更大的问题是employee_targets FK的task验证失败,在封闭的TaskSerializercreate方式指定它们之前。

1 个答案:

答案 0 :(得分:0)

你可以试试这个:

class EmployeeSerializer(serializers.ModelSerializer):
    name = serializers.CharField()
    email = serializers.CharField()

    class Meta:
        depth = 2
        model = Employee