python - Django休息框架: Password not hashing properly on update

标签 python django serialization passwords django-rest-framework

我正在尝试使用 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() (由父类(super class) ModelViewSet 提供),因为它应该自动调用序列化器的 save(),而后者又应该调用序列化器的 update( )。由于它不起作用,我还尝试在 AccountViewSet 中实现我自己的 update() ,其风格与覆盖相应的 create() 方法相同,但这似乎也不起作用。事实上,在这两种情况下,我什至无法验证序列化器的 update() 是否被调用,这让我认为我的序列化器的 update() 方法没有被调用,而是调用了它的父类(super class)的 update() ,这会解释密码没有被散列。显然,就调用我自己的序列化器的 update() 方法而言,我做错了什么,但我不知道是什么,也找不到任何其他真正解决这个问题的答案。

最佳答案

我不知道您的代码的问题,但请尝试 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

关于python - Django休息框架: Password not hashing properly on update,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34717936/

相关文章:

python - Python 中带有额外参数的父方法

django - 自定义模板加载器 Django

c# - 复杂数据模型和json.net序列化问题

java - @ResponseBody 使用 ArrayLists 序列化错误

python - Python 抽认卡程序中的单词对象

python - 系统退出(): is there a less extreme alternative?

python - 如何找出 Pandas 中使用的编码

python - Django ValueError 无法分配 "' 测试 '": "Profile.artist"必须是 "Artist"实例

python - 在 Django 模型中的字段更新

c# - 使用另一个更轻的对象序列化具有虚拟属性的对象