gpt4 book ai didi

python - 在管理面板上注册用户时不调用 Django 自定义用户管理器

转载 作者:行者123 更新时间:2023-12-05 03:23:53 24 4
gpt4 key购买 nike

在 Django 管理面板上创建用户时,objects = CustomUserManager() 不会被执行。但是,当我使用 python manage.py createsuperuser 从 CLI 创建 super 用户时,会执行 objects = CustomUserManager()

这是模型文件

class CustomUser(AbstractUser):
username = None
email = models.EmailField(_('email address'), unique=True)
name = models.CharField(verbose_name=_("first name"), max_length=50)
stripe_customer_id = models.CharField(max_length=120)

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']

objects = CustomUserManager()

def __str__(self):
return self.name

这是自定义用户管理器

class CustomUserManager(BaseUserManager):

def create_user(self, email, password, name,**extra_fields):

if not email:
raise ValueError(_('The Email must be set'))
email = self.normalize_email(email)
customer = stripe.Customer.create(
email=email,
name=name,
)
user = self.model(email=email,name=name, stripe_customer_id=customer.id ,**extra_fields)


user.set_password(password)
user.save()
return user

def create_superuser(self, email, password,name,**extra_fields):
"""
Create and save a SuperUser with the given email and password.
"""
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)

if extra_fields.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff=True.'))
if extra_fields.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True.'))
return self.create_user(email, password, name,**extra_fields)

下面是我注册管理面板的方法。

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import CustomUser
from django.utils.translation import gettext_lazy as _


class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
....

admin.site.register(CustomUser, CustomUserAdmin)

下面是CustomUserCreationForm

class CustomUserCreationForm(UserCreationForm):

class Meta:
model = CustomUser
fields = "__all__"

最佳答案

UserAdmin 依赖于 ModelAdmin 中的实现来构建实例、验证表单,然后保存实例,而不是调用模型管理器上的自定义方法。

调用链:ModelAdmin.add_view() → ... → self._changeform_view(),调用:

  • (i) form.is_valid() (ModelForm)→ ... → self._post_clean()self.instance = construct_instance(...) ,
  • (ii) self.save_form(...)new_object = form.save(commit=False)(属于 BaseModelForm)返回 self.instance
  • (iii) self.save_model(..., new_object, ...)obj.save()

您可以覆盖 ModelAdmin.save_form 以调用自定义用户管理器的 create_user 方法并替换 form.instance:

class CustomUserAdmin(UserAdmin):
model = CustomUser
fieldsets = (
(None, {'fields': (model.USERNAME_FIELD, 'name', 'password')}),
) + UserAdmin.fieldsets[2:]
add_fieldsets = (
(None, {'fields': (model.USERNAME_FIELD, 'name', 'password1', 'password2')}),
)
ordering = (model.USERNAME_FIELD,)

def save_form(self, request, form, change):
if not change:
form.instance = self.model.objects.create_user(
form.cleaned_data['email'],
form.cleaned_data['password1'],
form.cleaned_data['name'],
)
return super().save_form(request, form, change)

⚠️ 注意在通常的调用链中 save_form() 不会调用 obj.save(),因为 ModelAdmin 处理多个表单集和m2m 模型,而 CustomUserManager.create_user 会调用 user.save()。可以在已知范围的 UserAdmin 中更改此行为,但您可以考虑将 CustomUserManager.create_user 拆分为 CustomUserManager.construct_instance CustomUserManager.save_new_model(将 stripe.Customer.create(...)user.save() 移到此处)。

关于python - 在管理面板上注册用户时不调用 Django 自定义用户管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72430236/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com