django - 对自定义 Django 用户模型的任何更改都在 Admin 中完全被忽略
问题描述
我通过扩展 AbstractUser 而不是 AbstractBaseUser 自定义了 User 模型,因为我不需要删除用户名,我只需要通过电子邮件对用户进行身份验证,我仍然想使用 Django 附带的身份验证系统。因此,我只是将电子邮件地址定义为用户名,并在任何迁移之前扩展了 AbstractUser。
但是管理员没有认识到这一点,并且完全忽略了我在 admin.py 中指定的内容,除了注册指令。这是我的 admin.py 的内容
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from .models import User as CustomUser
from .forms import UserChangeForm, UserCreationForm
# from django.utils.translation import ugettext_lazy as _
# I obviously tried by extending UserAdmin too, no result
class CustomUserAdmin(admin.ModelAdmin):
add_form = UserCreationForm
form = UserChangeForm
model = CustomUser
fields = ('email')
# commenting or uncommenting the following doesn't change anything
"""
list_display = ('email', 'is_staff', 'is_active',)
list_filter = ('email', 'is_staff', 'is_active',)
exclude = ('first_name',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Permissions', {'fields': ('is_staff', 'is_active')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2', 'is_staff', 'is_active')}
),
)
search_fields = ('email',)
ordering = ('email',)
"""
admin.site.register(CustomUser, BaseUserAdmin)
我尝试了一切,但没有任何效果。我无法在“添加用户”表单中添加电子邮件字段,也无法从http://127.0.0.1:8000/admin/users/user/中删除名字和姓氏
似乎 Django 内置 Admin 忽略了在扩展 AbstractUser 的任何类中所做的任何更改
显然,settings.py 中的一切都是正确的:
INSTALLED_APPS = [
'users',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
# this is necessary for the custom user model and must to be taken into account before any migration will occur.
AUTH_USER_MODEL = 'users.User'
模型.py:
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _
class CustomUserManager(BaseUserManager):
"""
Custom user model manager where email is the unique identifier for
authentication instead of username.
Between the username field (email) and password, you must put all
the required fields. extra_fields must contain all the optional
fields.
"""
def create_user(self, email, username, password, **extra_fields):
"""
Create and save a User with the given email and password.
"""
if not email:
raise ValueError(_('The Email must be set'))
if not username:
raise ValueError("Users must have an Username")
user = self.model(
email = self.normalize_email(email),
username=username,
)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email=email,
username=username,
password=password
)
user.is_admin = True
user.is_staff=True
user.is_superuser=True
user.save(using=self._db)
return user
"""
This model behaves identically to the default user model, but you’ll be able to customize it in the future if the need arises. This is the recommended behavior
"""
class User(AbstractUser):
email = models.EmailField(_('email address'), unique=True)
USERNAME_FIELD = 'email'
"""
The REQUIRED_FIELDS = ['username'] must be present, otherwise the following error will arise:
TypeError: create_superuser() missing 1 required positional argument: 'username'
"""
REQUIRED_FIELDS = ['username']
objects = CustomUserManager()
def getEmailField(self):
return self.email
def __str__(self):
return self.email
表格.py:
class UserChangeForm(auth_forms.UserChangeForm):
class Meta(auth_forms.UserChangeForm.Meta):
model = CustomUser
fields = '__all__'
class UserCreationForm(auth_forms.UserCreationForm):
class Meta(auth_forms.UserCreationForm.Meta):
model = CustomUser
fields = '__all__'
显然,我在 fields = 'whatever' 中尝试了几件事,但我尝试的任何更改都被愉快地忽略了,管理员将始终以与默认方式相同的方式显示数据和表单。
我的看法.py.......
from django.shortcuts import render, redirect
from django.urls import reverse
from django.contrib.auth import login
from users.forms import CustomUserCreationForm
from django.template import RequestContext
def dashboard(request):
return render(request, "users/dashboard.html")
def register(request):
if request.method == "GET":
return render(
request, "users/register.html",
{"form": CustomUserCreationForm}
)
elif request.method == "POST":
form = CustomUserCreationForm(request.POST)
if form.is_valid():
# the form.cleaned_data must be used after calling
# the form.is_valid method.
# if(email_matches(form.cleaned_data["email"], form.cleaned_data["email2"])):
user = form.save()
login(request, user)
return redirect(reverse("dashboard"))
context = {
"form": form,
}
return render(request, "users/register.html", context)
def home_page(request):
return render(request, "home_page.html")
我在某处读到无法覆盖 AbstractUser 类中的任何内容,为此,我必须直接扩展 AbstractBaseUser 类。
这对管理表格也有效吗?毕竟,我并没有覆盖任何东西,我只是想在“管理员添加用户”表单中显示电子邮件地址。
但是假设我不能真正定制来自 AbstractUser 的任何东西。为什么会这样?这不是今天的问题。我已经尝试了解这种行为一个多星期了,文档和互联网都没有任何帮助。
解决方案
而不是扩展admin.ModelAdmin
for CustomUserAdmin
,你应该做这样的事情 -
class CustomUserAdmin(BaseUserAdmin):
...
...
然后请像这样更正您的模型注册行-
admin.site.register(CustomUser, CustomUserAdmin)
PS 不要忘记取消注释您已评论的行。
推荐阅读
- python - 如何使用 numpy 随机选择来获得具有相同数字的逐渐更长的序列?
- sql - 如何根据不同的行值在变量中创建新级别?
- arcgis - 当我使用 CDO 和 ArcGIS 从 netCDF 文件中提取同一网格点的数据时,为什么会得到不同的值?
- docker - 在 Windows 服务器上拉取 docker 映像时连接被拒绝
- c# - 当表单在 Blazor 服务器应用程序中具有有效状态时启用按钮
- weblogic12c - Oracle Service Bus 错误:ClassCastException:无法将 CountingRequestWrapper 强制转换为 ServletRequestImpl
- sql - 将连接查询中的重复值限制为仅显示第一个实例
- windows - 如何在 macOS 和 Windows 之间管理 docker-compose.override.yml 文件?
- nginx-reverse-proxy - 使用 nginx proxy_pass 在浏览器中保留 url 不起作用
- python - Tensorflow:使用 Tensorflow 2.5.0 将 Save_mode.pb 转换为 freeze_graph.pb