[英]Passwords are not hashed with Django as well as some missing columns
I'm not sure why my passwords are not hashed when creating a new custom user (email as username) using Django Rest Framework我不确定为什么在使用 Django Rest Framework 创建新的自定义用户(电子邮件作为用户名)时我的密码没有被散列
This is what I see in postgres.这是我在 postgres 中看到的。 Not sure why my admin/staff/active columns aren't showing up either even after migrating不知道为什么我的 admin/staff/active 列即使在迁移后也没有显示
models.py模型.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class UserManager(BaseUserManager):
def create_user(self, email, password=None, first_name=None, last_name=None, is_active=True, is_staff=False, is_admin=False):
if not email or not first_name or not last_name:
raise ValueError('Email is required')
if not password:
raise ValueError('Password is required')
if not first_name:
raise ValueError('First name is required')
if not last_name:
raise ValueError('Last name is required')
user_object = self.model(
email=self.normalize_email(email),
first_name=first_name,
last_name=last_name,
active=is_active,
staff=is_staff,
admin=is_admin,
)
user_object.set_password(password) # change password
user_object.save(self._db)
return user_object
def create_staff_user(self, email, first_name, last_name, password=None):
staff_user_object = self.create_user(email, first_name, last_name, password, is_staff=True)
return staff_user_object
def create_superuser(self, email, first_name, last_name, password=None):
super_user_object = self.create_user(email, first_name, last_name, password, is_staff=True, is_admin=True)
return super_user_object
class User(AbstractBaseUser):
email = models.EmailField(unique=True, max_length=255)
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
date_joined = models.DateTimeField(auto_now_add=True) # joined timestamp
is_active = models.BooleanField(default=True) # Can login?
is_staff = models.BooleanField(default=False) # staff user, non super user
is_admin = models.BooleanField(default=False) # super user?
objects = UserManager()
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = [] # email and passwords are required by default
settings.py设置.py
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', # Using Bcrypt to store passwords
views.py视图.py
class UserList(generics.ListCreateAPIView):
""" List all Users, or create a new User. """
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetail(generics.RetrieveUpdateDestroyAPIView):
""" Retrieve, update or delete a User instance. """
queryset = User.objects.all()
serializer_class = UserSerializer
]
urls.py网址.py
urlpatterns = [
path('accounts/', views.UserList.as_view()),
path('accounts/<int:pk>/', views.UserDetail.as_view()),
]
serializer.py序列化程序.py
from rest_framework import serializers
from .models import User
from properties.models import Property
class UserSerializer(serializers.ModelSerializer):
properties = serializers.PrimaryKeyRelatedField(many=True, queryset=Property.objects.all())
class Meta:
model = User
fields = '__all__'
The DRF serializer calls the default create()
method of the model and it won't call the .set_password()
method. DRF 序列化程序调用模型的默认create()
方法,它不会调用.set_password()
方法。 So, You have to call the method explicitly in your create() method of UserSerializer因此,您必须在UserSerializer 的create()方法中显式调用该方法
class UserSerializer(serializers.ModelSerializer):
# other code
def create(self, validated_data): password = validated_data.pop('password', None) user_instance = super().create(validated_data) if password: user_instance.set_password(password) user_instance.save() return user_instance
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.