Django: просмотр пользовательского пароля DRF и сериализатор не работают - PullRequest
0 голосов
/ 27 мая 2020

Я определил класс сериализатора и класс представления для изменения пароля. Как обычно, пользователю необходимо ввести старый пароль, затем два раза новый пароль для подтверждения. Я использую AbstractBaseUser для реализации специального пользователя. Я определил old_password_validator и new_password_validator с предложениями из этого потока , хотя я не знаю, как заставить его работать.

Я использую djangorestframework_simplejwt для всех видов аутентификации.

Мой класс сериализатора:

class ChangePasswordSerializer(serializers.ModelSerializer):
    old_password = serializers.CharField(required=True, write_only=True)
    new_password = serializers.CharField(required=True, write_only=True)
    re_new_password = serializers.CharField(required=True, write_only=True)

    def update(self, instance, validated_data):

        instance.password = validated_data.get('password', instance.password)

        if not validated_data['new_password']:
              raise serializers.ValidationError({'new_password': 'not found'})

        if not validated_data['old_password']:
              raise serializers.ValidationError({'old_password': 'not found'})

        if not instance.check_password(validated_data['old_password']):
              raise serializers.ValidationError({'old_password': 'wrong password'})

        if validated_data['new_password'] != validated_data['re_new_password']:
            raise serializers.ValidationError({'passwords': 'passwords do not match'})

        if validated_data['new_password'] == validated_data['re_new_password'] and instance.check_password(validated_data['old_password']):
            instance.set_password(validated_data['new_password'])
            instance.save()
            return instance

    class Meta:
        model = User
        fields = ['old_password', 'new_password','re_new_password']

Я определил свой класс представления следующим образом:

class ChangePasswordView(generics.UpdateAPIView):
    permission_classes = (permissions.IsAuthenticated,)

    def update(self, request, *args, **kwargs):
        serializer = ChangePasswordSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
             serializer.save()
             return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Когда я ввел значения, заголовки и запустил почтальон, я получил это ошибка:

Получил TypeError при звонке User.objects.create(). Это может быть связано с тем, что у вас есть записываемое поле в классе сериализатора, которое не является допустимым аргументом для User.objects.create(). Возможно, вам придется сделать это поле доступным только для чтения или переопределить метод ChangePasswordSerializer.create (), чтобы справиться с этим правильно.

Я ничего не могу сделать из этого сообщения об ошибке.

1 Ответ

1 голос
/ 27 мая 2020

Вам необходимо передать аргумент экземпляра для ChangePasswordSerializer:

serializer = ChangePasswordSerializer(instance=self.request.user, data=request.data)

Если вы не передаете аргумент экземпляра, сериализатор запускает метод create () при вызове save () в противном случае ( когда указан аргумент экземпляра) вызывается update ().

...