У меня проблемы с использованием patch метода внутри ModelViewSet для моей пользовательской модели User. Вот код:
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
Я установил разрешение для того, чтобы разрешить только суперпользователю доступ к этому представлению. Проблема возникает при попытке выполнить патч. Например, если я попытаюсь изменить атрибут is_staff на Ложь для пользователя, использующего Почтальон с PATCH, и "http://localhost: 8000 / users / USER_ID ", Я получаю следующую ошибку:
django .db.utils.IntegrityError: нулевое значение в столбце «электронная почта» нарушает ненулевое ограничение ПОДРОБНОЕ ОПИСАНИЕ tCQ9zZk1uOdJD2F7L9BQRFFDbz1GXJ ..., 2020-04-18 20: 02: 57.052639 + 00, null, t, t, t).
Похоже, django просит меня предоставить каждое поле для Модель пользователя ( email , is_active , is_staff , is_admin ), который, по моему мнению, не имеет смысла, что это PATCH запрос. Чтобы решить эту проблему, я изменил метод update моего UserSerializer следующим образом:
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
Это работает сейчас, но я хотел бы знать хорошее ли это решение На мой взгляд, это не «канонический» способ решения проблемы. Я также пытался переопределить метод partal_update (следуя ответам других StackOverflow) внутри моего UserViewSet, без результатов.