简体   繁体   English

Django休息框架用户注册?

[英]Django rest framework user registration?

I am following this tutorial but facing these problems I can't fix: 我正在按照本教程,但面对这些问题,我无法修复:

  1. Upon registering user, I can not log in with that user to the api because the password is not hashed "Invalid password format or unknown hashing algorithm." 注册用户后,我无法使用该用户登录到api,因为密码未经过哈希“无效的密码格式或未知的哈希算法”。 in admin 在管理员
  2. I cannot post to 'api/accounts' or see the form in the browseable api when I am not logged in to the api 当我没有登录到api时,我无法发布到'api / accounts'或在可浏览的api中看到该表单

My code: 我的代码:

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

I tried the accepted answer in DRF 3.0.2 and it didn't work. 我在DRF 3.0.2中尝试了接受的答案但它没有用。 The password was not being hashed. 密码没有被哈希。

Instead, override the create method in your model serializer 而是覆盖模型序列化器中的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

This hashes the password when you create a user using the rest framework, not post_save 当您使用rest框架而不是post_save创建用户时,这会散列密码

Another approach for DRF 3.X: 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

I've used wsgeorge 's solution to build my own. 我用wsgeorge的解决方案来构建自己的解决方案。 A blank User object is created just so I can use .set_password() : 创建一个空白的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)

Different from his answer, I do not save the user myself. 与他的回答不同,我不会自己保存用户。 I leave that to the parent class calling super . 我把它留给调用super的父类。

Please note that set_password() does NOT save the object and since you have called the super first, your object is already saved with raw password. 请注意,set_password()不会保存对象,因为您先调用了超级对象,所以您的对象已经使用原始密码保存。

Just simply use post_save() to save the 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()

Override create of model serialzier 覆盖模型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)

Be sure to import 一定要导入

from django.contrib.auth.hashers import make_password

We can write a signal in User to solve this. 我们可以在User中写一个信号来解决这个问题。

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


pre_save.connect(create_hash, sender=User)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM