Django休息框架用户注册?

时间:2014-04-12 18:51:42

标签: python django rest serialization django-rest-framework

我关注this tutorial但面对这些问题我无法解决:

  1. 注册用户后,我无法使用该用户登录api,因为密码未经过哈希处理 “无效的密码格式或未知的散列算法。”在管理员
  2. 当我没有登录到api时,我无法发布到'api / accounts'或在可浏览的api中看到该表单
  3. 我的代码:

    from django.contrib.auth.models import User
    from rest_framework import serializers
    
    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields = ('password', 'first_name', 'last_name', 'email')
            write_only_fields = ('password',)
    
        def restore_object(self, attrs, instance=None):
            # call set_password on user object. Without this
            # the password will be stored in plain text.
            user = super(UserSerializer, self).restore_object(attrs, instance)
            user.set_password(attrs['password'])  #somehow not hashing
            return user
    

6 个答案:

答案 0 :(得分:13)

我在DRF 3.0.2中尝试了接受的答案但它没有用。密码没有被哈希。

而是覆盖模型序列化程序中的create方法

    def create(self, validated_data):
        user = User(email=validated_data['email'], username=validated_data['username'])
        user.set_password(validated_data['password'])
        user.save()
        return user

当您使用其余框架而不是post_save

创建用户时,这会对密码进行哈希处理

答案 1 :(得分:6)

DRF 3.X的另一种方法:

from django.contrib.auth import get_user_model
from django.contrib.auth.hashers import make_password

    def create(self, validated_data):    
        if validated_data.get('password'):
            validated_data['password'] = make_password(
                validated_data['password']
            )

        user = get_user_model().objects.create(**validated_data)

        return user

答案 2 :(得分:3)

我已经使用wsgeorge的解决方案来构建自己的解决方案。创建了一个空白的User对象,因此我可以使用.set_password()

def create(self, validated_data):
    user = User()
    user.set_password(validated_data['password'])
    validated_data['password'] = user.password
    return super(UserSerializer, self).create(validated_data)

与他的答案不同,我不会自己保存用户。我把它留给调用super的父类。

答案 3 :(得分:1)

请注意,set_password()不保存对象,因为您先调用了超级对象,所以您的对象已使用原始密码保存。

只需使用post_save()保存密码即可。

def post_save(self, obj, created=False):
    """
    On creation, replace the raw password with a hashed version.
    """
    if created:
        obj.set_password(obj.password)
        obj.save()

答案 4 :(得分:0)

覆盖模型serialzier的创建

def create(self, validated_data):
        if validated_data.get('password'):
            validated_data['password'] = make_password(validated_data['password'])
        return super(UserSerializer, self).create(validated_data)

请确保导入

from django.contrib.auth.hashers import make_password

答案 5 :(得分:-1)

我们可以在用户中写一个信号来解决这个问题。

def create_hash(sender, instance=None, *args, **kwargs):
passwd = instance.password
instance.set_password(passwd)


pre_save.connect(create_hash, sender=User)