Django:DRF 自定义密码更改视图和序列化器不工作
Django: DRF custom password change view and serializer not working
我定义了一个序列化程序 class 和一个视图 class 来执行密码更改。与往常一样,用户需要输入旧密码,然后输入新密码两次进行确认。我正在使用 AbstractBaseUser
来实现自定义用户。我根据这个 的建议定义了 old_password_validator
和 new_password_validator
,尽管我不知道如何让它工作。
我正在使用 djangorestframework_simplejwt 进行各种身份验证。
我的序列化器class:
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:
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)
当我在 postman 中输入值 headers 和 运行 时,我得到了这个错误:
调用 User.objects.create()
时得到一个 TypeError
。这可能是因为您在序列化程序 class 上有一个可写字段,它不是 User.objects.create()
的有效参数。您可能需要使字段 read-only 或重写 ChangePasswordSerializer.create() 方法才能正确处理此问题。
我无法从这个错误陈述中得出任何结论。
您需要为 ChangePasswordSerializer 传递实例参数:
serializer = ChangePasswordSerializer(instance=self.request.user, data=request.data)
当您不传递实例参数时,序列化程序会在您调用 save() 时运行 create() 方法,否则(当提供实例参数时)会调用 update()。
我定义了一个序列化程序 class 和一个视图 class 来执行密码更改。与往常一样,用户需要输入旧密码,然后输入新密码两次进行确认。我正在使用 AbstractBaseUser
来实现自定义用户。我根据这个 old_password_validator
和 new_password_validator
,尽管我不知道如何让它工作。
我正在使用 djangorestframework_simplejwt 进行各种身份验证。
我的序列化器class:
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:
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)
当我在 postman 中输入值 headers 和 运行 时,我得到了这个错误:
调用 User.objects.create()
时得到一个 TypeError
。这可能是因为您在序列化程序 class 上有一个可写字段,它不是 User.objects.create()
的有效参数。您可能需要使字段 read-only 或重写 ChangePasswordSerializer.create() 方法才能正确处理此问题。
我无法从这个错误陈述中得出任何结论。
您需要为 ChangePasswordSerializer 传递实例参数:
serializer = ChangePasswordSerializer(instance=self.request.user, data=request.data)
当您不传递实例参数时,序列化程序会在您调用 save() 时运行 create() 方法,否则(当提供实例参数时)会调用 update()。