使用SlugRelatedField

时间:2017-05-20 19:35:55

标签: django-rest-framework

目前我在ModelSerializer中使用SlugRelatedField来表示m2m-Field。

manager = serializers.SlugRelatedField(
                     many=True, 
                     queryset=get_user_model().objects.all(),
                     slug_field='username', 
                     required=False,
                     allow_null=True)

如果我现在发送补丁请求,例如 'manager': 'user1''manager: ['user1', 'user2']按预期工作。

但是当我发送一个空数组'manager': []

时,我怎么能实现m2m字段被清除

此刻没有任何反应,当我这样做的时候。 如果我尝试用'manager': ''清除它,我会得到一个“用户名=不存在的对象”错误。

也许SlugRelatedField对我来说不是正确的选择?我只想用他们的用户名代替他们的pk来处理用户。

修改

我可以执行PUT请求而不发送'manager'来清除它。 是否可能无法使用PATCH请求清除m2m字段?

r = requests.patch('http://localhost:8000/api/projects/dfo2/', auth = ('lala','lilu'), data = {'developer': []} )

结果:

{'manager': ['peter', 'fllow'], 'description': '','name_short': 'dfo2', 'developer': ['peter'], 'name': 'asdf'}

有效的是:

r = requests.patch('http://localhost:8000/api/projects/dfo2/',
                auth = ('lala','lilu'), 
                data = '{"developer": []}',
                headers = {'Content-type': 'application/json'}
                )

但为什么这不起作用:

r = requests.patch('http://localhost:8000/api/projects/dfo2/',
                auth = ('lala','lilu'), 
                data = {"developer": []},
                headers = {'Content-type': 'application/x-www-form-urlencoded'}
                )

1 个答案:

答案 0 :(得分:0)

如果没有看到完整的代码,很难知道,但通常看起来你并没有正确处理数据。我总是向人们提供DRF的一条建议是将序列化器视为提供和验证数据的工具,但不一定要描述如何处理它。

考虑到这一点,我建议你尝试类似下面的内容,但是如果没有看到模型和完整的序列化代码,那就很难了:

class Projects(models.Model):
    managers = models.ManyToManyField('auth.Users')


class ProjectSerializer(serializers.Serializer):
    managers = serializers.SlugRelatedField(
                     many=True,
                     source='managers.all',
                     queryset=get_user_model().objects.all(),
                     slug_field='username', 
                     required=False,
                     allow_null=True)

    def update(self, instance, validated_data):
        [instance.managers.add(manager) for manager in validated_data['managers']
        return instance