Django休息框架用户注册?

use*_*525 13 python django rest serialization django-rest-framework

我正在按照本教程,但面对这些问题,我无法修复:

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

我的代码:

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
Run Code Online (Sandbox Code Playgroud)

wsg*_*rge 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
Run Code Online (Sandbox Code Playgroud)

当您使用rest框架而不是post_save创建用户时,这会散列密码

  • 使用`User.objects.create_user(**validated_data)`来创建用户(使用散列密码)而不是两行进行操作可能更容易 (4认同)

psy*_*ok7 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
Run Code Online (Sandbox Code Playgroud)


use*_*525 1

请注意,set_password() 不会保存对象,并且由于您首先调用了 super,因此您的对象已使用原始密码保存。

只需简单地使用 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()
Run Code Online (Sandbox Code Playgroud)