Django 自定义用户模型无法从管理站点加密密码
Django Custom User Model Failes to encrypt password from admin site
我通过继承 AbstractBaseUser、PermissionsMixin 创建了一个自定义用户模型,还创建了一个用于创建用户和超级用户的自定义管理器。但是当我尝试从 Django 管理站点添加新用户时,它无法加密密码字段并保留纯文本。
但是当我使用 Serializer 的创建函数从客户端站点请求时,它工作正常。
自定义模型Class代码:
from django.db import models
from django.contrib.auth.models import (AbstractBaseUser, PermissionsMixin)
from .managers import UserManager
class CustomUser(AbstractBaseUser, PermissionsMixin):
"""
Responsible for handleing App user's data
"""
username = models.CharField(max_length=20,unique=True)
email = models.EmailField(max_length=255, unique=True)
first_name = models.CharField(max_length=50, blank=True, null=True)
last_name = models.CharField(max_length=50, blank=True, null=True)
is_active = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_authority = models.BooleanField(default=False)
is_general_user = models.BooleanField(default=False)
timestamps = models.DateTimeField(auto_now_add=True)
update_on = models.DateTimeField(auto_now=True)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
def __str__(self):
return self.username
自定义管理器:
from django.contrib.auth.models import BaseUserManager
class UserManager(BaseUserManager):
def create_user(self, email, password=None, **kwargs):
"""
Creates and saves a new user
"""
user = self.model(email=self.normalize_email(email), **kwargs)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
"""
For superusers registration
"""
user = self.create_user(email=email, password=password)
user.is_staff = True
user.is_superuser = True
user.is_active = True
user.is_authority = True
user.save(using=self._db)
return user
序列化 Class 效果很好:
class UserCommonDetailSerializers(UserAdminDetailSerializers):
"""
Responsible for serializing user's detail data
"""
password = serializers.CharField(write_only=True, required=False)
first_name = serializers.CharField(required=False)
last_name = serializers.CharField(required=False)
is_active = serializers.BooleanField(read_only=True)
is_staff = serializers.BooleanField(read_only=True)
is_authority = serializers.BooleanField(read_only=True)
is_general_user = serializers.BooleanField(read_only=True)
class Meta:
model = CustomUser
fields = (
'url',
'id',
'username',
'email',
'first_name',
'last_name',
'password',
'is_active',
'is_staff',
'is_authority',
'is_general_user')
def create(self, validated_data):
user = User.objects.create_user(
username=validated_data['username'],
email=validated_data['email'],
password=validated_data['password'])
return user
如果您正在实施自己的用户模型,那么您还必须实施自定义用户管理员 class,如图 here。
示例:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth import get_user_model
User = get_user_model()
@admin.register(User)
class UserAdmin(BaseUserAdmin):
list_filter = ["is_staff"]
fieldsets = [
(None, {"fields": ["username", "email", "password"]}),
(
"Other info",
{
"fields": [
"first_name",
"last_name",
],
},
),
]
add_fieldsets = [
(
None,
{
"fields": [
"username",
"email",
"first_name",
"last_name",
"password1",
"password2",
]
},
),
]
注意 password1
和 password2
的用法。
你可以试试这个:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth import get_user_model
from django.utils.translation import gettext as _
class AccountAdmin(UserAdmin):
ordering = ['id']
list_display = ['email']
readonly_fields = ('date_joined','last_login')
fieldsets = (
(_("User Details"), {'fields': ('email', 'password')}),
(_("Account Details"), {'fields': ('date_joined', 'last_login')}),
(_("Permission"), {'fields': ('is_active', 'is_staff', 'is_admin')}),
)
add_fieldsets = (
("User Details", {'fields': ('email', 'password1', 'password2')}),
("Permission", {'fields': ('is_active', 'is_staff', 'is_admin')}),
)
admin.site.register(get_user_model(), AccountAdmin)
我通过继承 AbstractBaseUser、PermissionsMixin 创建了一个自定义用户模型,还创建了一个用于创建用户和超级用户的自定义管理器。但是当我尝试从 Django 管理站点添加新用户时,它无法加密密码字段并保留纯文本。
但是当我使用 Serializer 的创建函数从客户端站点请求时,它工作正常。
自定义模型Class代码:
from django.db import models
from django.contrib.auth.models import (AbstractBaseUser, PermissionsMixin)
from .managers import UserManager
class CustomUser(AbstractBaseUser, PermissionsMixin):
"""
Responsible for handleing App user's data
"""
username = models.CharField(max_length=20,unique=True)
email = models.EmailField(max_length=255, unique=True)
first_name = models.CharField(max_length=50, blank=True, null=True)
last_name = models.CharField(max_length=50, blank=True, null=True)
is_active = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_authority = models.BooleanField(default=False)
is_general_user = models.BooleanField(default=False)
timestamps = models.DateTimeField(auto_now_add=True)
update_on = models.DateTimeField(auto_now=True)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
def __str__(self):
return self.username
自定义管理器:
from django.contrib.auth.models import BaseUserManager
class UserManager(BaseUserManager):
def create_user(self, email, password=None, **kwargs):
"""
Creates and saves a new user
"""
user = self.model(email=self.normalize_email(email), **kwargs)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
"""
For superusers registration
"""
user = self.create_user(email=email, password=password)
user.is_staff = True
user.is_superuser = True
user.is_active = True
user.is_authority = True
user.save(using=self._db)
return user
序列化 Class 效果很好:
class UserCommonDetailSerializers(UserAdminDetailSerializers):
"""
Responsible for serializing user's detail data
"""
password = serializers.CharField(write_only=True, required=False)
first_name = serializers.CharField(required=False)
last_name = serializers.CharField(required=False)
is_active = serializers.BooleanField(read_only=True)
is_staff = serializers.BooleanField(read_only=True)
is_authority = serializers.BooleanField(read_only=True)
is_general_user = serializers.BooleanField(read_only=True)
class Meta:
model = CustomUser
fields = (
'url',
'id',
'username',
'email',
'first_name',
'last_name',
'password',
'is_active',
'is_staff',
'is_authority',
'is_general_user')
def create(self, validated_data):
user = User.objects.create_user(
username=validated_data['username'],
email=validated_data['email'],
password=validated_data['password'])
return user
如果您正在实施自己的用户模型,那么您还必须实施自定义用户管理员 class,如图 here。
示例:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth import get_user_model
User = get_user_model()
@admin.register(User)
class UserAdmin(BaseUserAdmin):
list_filter = ["is_staff"]
fieldsets = [
(None, {"fields": ["username", "email", "password"]}),
(
"Other info",
{
"fields": [
"first_name",
"last_name",
],
},
),
]
add_fieldsets = [
(
None,
{
"fields": [
"username",
"email",
"first_name",
"last_name",
"password1",
"password2",
]
},
),
]
注意 password1
和 password2
的用法。
你可以试试这个:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth import get_user_model
from django.utils.translation import gettext as _
class AccountAdmin(UserAdmin):
ordering = ['id']
list_display = ['email']
readonly_fields = ('date_joined','last_login')
fieldsets = (
(_("User Details"), {'fields': ('email', 'password')}),
(_("Account Details"), {'fields': ('date_joined', 'last_login')}),
(_("Permission"), {'fields': ('is_active', 'is_staff', 'is_admin')}),
)
add_fieldsets = (
("User Details", {'fields': ('email', 'password1', 'password2')}),
("Permission", {'fields': ('is_active', 'is_staff', 'is_admin')}),
)
admin.site.register(get_user_model(), AccountAdmin)