我关注this tutorial但面对这些问题我无法解决:
我的代码:
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
答案 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)