自定义用户类,从表单创建用户时不会对密码进行哈希处理

Custom User class, password isn't hashed when creating user from the form

提问人:DR4NKR1D3R 提问时间:10/31/2022 最后编辑:DR4NKR1D3R 更新时间:11/1/2022 访问量:58

问:

我已经编写了自己的 AbstractBaseUser 和 BaseUserManager。通过终端创建用户和超级用户可以正常工作。但是通过表单创建用户存在问题。除密码字段外,所有用户字段都正确保存,该字段未进行哈希处理(使用 set_password()) 时)。我的 models.py:

from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager


class MyUserAccountManager(BaseUserManager):
    def create_superuser(self, email, first_name, last_name, password, **other_fields):
        other_fields.setdefault('is_staff', True)
        other_fields.setdefault('is_superuser', True)
        other_fields.setdefault('is_active', True)

        if other_fields.get('is_staff') is not True:
            raise ValueError(
                'Superuser must be assigned to is_staff=True.')
        if other_fields.get('is_superuser') is not True:
            raise ValueError(
                'Superuser must be assigned to is_superuser=True.')

        return self.create_user(email, first_name, last_name, password, **other_fields)

    def create_user(self, email, first_name, last_name, password, **other_fields):
        if not email or not first_name or not last_name or not password:
            raise ValueError('You must provide more data')

        email = self.normalize_email(email)
        user = self.model(email=email, first_name=first_name, last_name=last_name, **other_fields)
        user.set_password(password)
        user.save()
        return user


class MyUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField('Email address', unique=True, max_length=30)
    first_name = models.CharField('First name', max_length=30)
    last_name = models.CharField('Last name', max_length=30)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)

    objects = MyUserAccountManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    def __str__(self):
        return self.email

我 forms.py:

from django import forms
from .models import MyUser

class MyUserForm(forms.ModelForm):
    email = forms.CharField(widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
    first_name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First name', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
    last_name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Last name', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
    password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Password', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
    
    class Meta:
        model = MyUser
        fields = ['email',
                  'first_name',
                  'last_name',
                  'password']

我认为没有必要显示 views.py 和 html 文件(完整标准)。my form任何帮助都是值得赞赏的!

Python Django

评论


答:

1赞 David Smith 10/31/2022 #1

*来自脆皮形式。从脆皮形式的文档...

如果您不喜欢使用 *(星号)来表示必填字段,您有两种选择:

星号有一个星号字段类集。因此,您可以使用CSS规则隐藏它:

.asteriskField {
    display: none;
}

使用自定义模板覆盖模板。field.html