简体   繁体   English

密码不会与 Django 以及一些缺失的列一起散列

[英]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.

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