我正在尝试使用Django Rest Framework(通过PUT调用)更新自定义用户模型,虽然我可以正常更新模型的用户名和密码,但密码不会这样做:当我检查用户的时候密码通过django admin我得到“无效的密码格式或未知的散列算法。”
以下是我的views.py和serializers.py的相关部分:
class AccountViewSet(viewsets.ModelViewSet):
lookup_field = 'username'
queryset = Account.objects.all()
serializer_class = AccountSerializer
def get_permissions(self):
if self.request.method in permissions.SAFE_METHODS:
return (permissions.IsAdminUser(),)
if self.request.method == 'POST':
return (permissions.AllowAny(),)
return (permissions.IsAdminUser(),)
def create(self, request):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid(raise_exception=True):
Account.objects.create_user(**serializer.validated_data)
return Response(serializer.validated_data, status = status.HTTP_201_CREATED)
return Response({
'status': 'Bad request',
'message': 'Account could not be created with received data.'
}, status = status.HTTP_400_BAD_REQUEST)
_
class AccountSerializer(serializers.HyperlinkedModelSerializer):
password = serializers.CharField(write_only = True, required = False)
confirm_password = serializers.CharField(write_only = True, required = False)
def validate(self, data):
if data.get('password') != data.get('confirm_password'):
raise serializers.ValidationError("Passwords do not match.")
else:
temp = Account(email = data.get('email'), username = data.get('username'))
validate_password(data.get('password'), temp)
return data
class Meta:
model = Account
fields = (
'id',
'email',
'username',
'created_at',
'updated_at',
'password',
'confirm_password'
)
read_only_fields = (
'created_at',
'updated_at'
)
def create(self, validated_data):
return Account.objects.create(**validated_data)
def update(self, instance, validated_data):
for attr, value in validated_data.items():
if attr == 'password':
instance.set_password(value)
else:
setattr(instance, attr, value)
instance.save()
update_session_auth_hash(self.context.get('request'), instance)
return instance
现在,我的理解是我不应该覆盖AccountViewSet的update()(由超类ModelViewSet提供),因为它应该自动调用序列化程序的save(),而后者应该调用序列化程序的更新( )。由于它不起作用,我也尝试在AccountViewSet中实现我自己的update(),其方式与相应的create()方法被覆盖相同,但这似乎也不起作用。事实上,在这两种情况下,我甚至无法验证序列化程序的update()是否被调用,这使我认为我的序列化程序的update()方法没有被调用,而是调用了它的超类'update(),会解释密码没有被散列。显然我做错了,只要调用我自己的序列化程序的update()方法,但是我无法弄清楚什么,也找不到任何其他能够真正解决这个问题的答案。
答案 0 :(得分:1)
我不知道您的代码问题,但请从https://thinkster.io/django-angularjs-tutorial
尝试此序列化程序class AccountSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True, required=False)
confirm_password = serializers.CharField(write_only=True, required=False)
class Meta:
model = Account
fields = ('id', 'email', 'username', 'created_at', 'updated_at',
'first_name', 'last_name', 'tagline', 'password',
'confirm_password',)
read_only_fields = ('created_at', 'updated_at',)
def create(self, validated_data):
return Account.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.username = validated_data.get('username', instance.username)
instance.tagline = validated_data.get('tagline', instance.tagline)
instance.save()
password = validated_data.get('password', None)
confirm_password = validated_data.get('confirm_password', None)
if password and confirm_password and password == confirm_password:
instance.set_password(password)
instance.save()
update_session_auth_hash(self.context.get('request'), instance)
return instance