【发布时间】: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 要求我提供用户模型的每个字段(email、is_active、is_staff、is_admin),在我看来这是没有意义的,因为它是一个 PATCH 请求。 为了解决这个问题,我修改了 UserSerializer 的 update 方法,如下所示:
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 的答案),但没有结果。
【问题讨论】:
-
我认为在路由和URL中的问题,而不是视图,你必须删除http_method_name
标签: django django-rest-framework django-views patch django-serializer