【问题标题】:PATCH method not working in Django ModelViewSetPATCH 方法在 Django ModelViewSet 中不起作用
【发布时间】:2020-04-19 16:25:56
【问题描述】:

我在为我的自定义用户模型使用 ModelViewSet 中的 patch 方法时遇到问题。 代码如下:

views.py

@permission_classes([IsAdminUser])
    class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    http_method_names = ['get', 'post', 'patch', 'head', 'delete']

serializers.py

class UserSerializer(serializers.ModelSerializer):
class Meta:
    model = User
    fields = ('id',
              'email',
              'password',
              'is_active',
              'is_staff',
              'is_admin')
    extra_kwargs = {'password': {'write_only': True, 'required': True},
                    'is_active': {'default': True},
                    'is_staff': {'default': False},
                    'is_admin': {'default': False}}

def create(self, validated_data):
    self.is_valid(raise_exception=True)
    if validated_data['is_admin']:
        validated_data['is_staff'] = True
    user = User.objects.create_user(**validated_data)
    return user

def update(self, instance, validated_data):
    instance.email = validated_data.get('email')
    instance.is_active = validated_data.get('is_active')
    instance.is_staff = validated_data.get('is_staff')
    instance.is_admin = validated_data.get('is_admin')
    if instance.is_admin:
        instance.is_staff = True
    instance.save()
    return instance

我设置了一个权限,以便只允许超级用户访问这个视图。尝试执行修补程序时出现问题。例如,如果我尝试使用带有 PATCH 和“http://localhost:8000/users/USER_ID”的 Postman 将用户的 is_staff 属性更改为 False,我会收到以下错误:

django.db.utils.IntegrityError: "email" 列中的空值违反非空约束 详细信息:失败行包含 (1, pbkdf2_sha256$180000$6jePqBspO6xK$tCQ9zZk1uOdJD2F7L9BQRFFDbz1GXJ..., 2020-04-18 20:02:57.052639+00, null, t, t, t)。

似乎 django 要求我提供用户模型的每个字段(emailis_activeis_staffis_admin),在我看来这是没有意义的,因为它是一个 PATCH 请求。 为了解决这个问题,我修改了 UserSerializerupdate 方法,如下所示:

    def update(self, instance, validated_data):
        if validated_data.get('email') is not None:
            instance.email = validated_data.get('email')
        if validated_data.get('is_active') is not None:
            instance.is_active = validated_data.get('is_active')
        if validated_data.get('is_staff') is not None:
            instance.is_staff = validated_data.get('is_staff')
        if validated_data.get('is_admin') is not None:
            instance.is_admin = validated_data.get('is_admin')
        if instance.is_admin:
            instance.is_staff = True
        instance.save()
        return instance

现在可以了,但我想知道这是否是一个好的解决方案。在我看来,这不是解决问题的“规范”方式。我还尝试在我的 UserViewSet 中覆盖 partial_update 方法(遵循其他 StackOverflow 的答案),但没有结果。

【问题讨论】:

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


【解决方案1】:

我发现这篇上一篇文章非常有用django-rest-framework-serializer-update-method-does-not-save-object 问题出在序列化程序中。我已经更改了 UserSerializer 中覆盖的 update 方法,现在 PATCH 可以工作了

def update(self, instance, validated_data):
    if validated_data.get('is_admin'):
        validated_data['is_staff'] = True
    return super().update(instance, validated_data)

注意:不需要覆盖视图中的任何方法,只需将 'patch' 添加到 http_method_names 列表

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 2017-10-01
    • 1970-01-01
    • 2016-03-29
    • 2013-09-07
    • 2021-06-21
    • 2019-04-22
    相关资源
    最近更新 更多