为什么我的序列化程序会在验证数据上抛出TypeError?

时间:2015-09-04 18:53:06

标签: django django-rest-framework

我正在尝试修改我的EmployeeSerializer以在创建员工时创建相应的User对象。但是,在我的序列化程序的create()函数中,当我尝试保存新对象时,我得到以下TypeError:

TypeError: 'skills' is an invalid keyword argument for this function

这是我的Employee模型:

class Employee(models.Model):
    # ...snip...
    skills = models.ManyToManyField(Skill)
    # ...snip...

这里是EmployeeSerializer

class EmployeeSerializer(serializers.ModelSerializer):
    def create(self, validated_data):
        # Popping 'skills' here prevents the TypeError...
        # skills = validated_data.pop('skills', None)
        employee = Employee(**validated_data)
        employee.save()

        user = UserSerializer(data={
            'username': validated_data.get('email'),
            'password': self.initial_data['password'],
            'groups': self.initial_data['groups'],
            'user_permissions': self.initial_data['user_permissions']
        })

        user.is_valid(raise_exception=True)
        user.save()

        return employee

    class Meta:
        model = Employee

当我调用序列化程序时,我声明了一个skills参数,它显示在validated_data中(注意:我删除了无关的模型字段):

>>> em = EmployeeSerializer(data={'skills': []})
>>> em.is_valid()
True
>>> em.validated_data
OrderedDict([('skills', [])])

由于在模型中声明了skills,并且它通过了Serializer的验证,我希望这个新对象可以保存而不会发生意外。什么给出了什么?我做错了什么?

1 个答案:

答案 0 :(得分:2)

DRF 3.1目前不支持嵌套表示的写入操作。

您必须处理如何保存嵌套对象。

来自writable nested representations:

上的DRF文档
  

默认的ModelSerializer .create().update()方法没有   包括对可写嵌套表示的支持。

     

如果您支持可写的嵌套表示,则需要   编写处理保存倍数的.create().update()方法   对象。

您可以执行以下操作:

class EmployeeSerializer(serializers.ModelSerializer):

    def create(self, validated_data):
        skills_data = validated_data.pop('skills') # pop the 'skills' from validated data 
        employee = Employee(**validated_data) # create employee instance            
        employee.save() # save the employee object
        # here you can write the logic to obtain 'skill_object' from 'skills_data' and add them to 'employee' 
        # this can be done iteratively also if there are multiple skills
        employee.skills.add(skill_object) # attach skill object with employee using 'skills_data'
        ...

嵌套表示的上述约束仅适用于写操作。因此,您可以在skills中获得validated_data