You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义UserRegister模型注册用户时触发KeyError('password')问题

自定义UserRegister模型注册时KeyError('password')问题解决

问题现象

使用自定义UserRegister模型注册新用户时,触发KeyError: 'password',后台已成功创建用户,但无法实现注册后自动登录。

错误原因

  1. 表单配置冲突:CustomUserRegisterForm继承自UserCreationForm,但在Meta中排除了password字段,导致表单验证后cleaned_data中没有password键,视图中尝试获取form.cleaned_data["password"]直接触发KeyError。
  2. 认证逻辑不匹配自定义模型:自定义用户模型的USERNAME_FIELD设置为email,但视图中仍用username进行认证,不符合Django自定义用户的认证规则。
  3. 管理器方法参数顺序错误:create_superuser调用create_user时参数顺序颠倒,把username放在了email的位置,会导致创建超级用户时参数传递错误。
  4. 用户默认未激活:模型中is_active默认值为False,即使认证成功也无法登录系统。

解决步骤及修改代码

1. 修正表单配置

UserCreationForm会自动生成password1和password2字段用于密码确认,无需手动排除模型中的password字段。直接指定需要显示的字段即可:

# 表单代码修改
from django.contrib.auth.forms import UserCreationForm
from .models import UserRegister

class CustomUserRegisterForm(UserCreationForm):
    class Meta:
        model = UserRegister
        fields = ["username", "email", "age", "country", "county", "city"]  # 明确需要展示的字段

2. 修正视图认证逻辑

  • 不要从cleaned_data中取password,直接使用表单保存后的用户对象;
  • 按照自定义模型的USERNAME_FIELD(即email)进行认证;
  • 注册时主动激活用户(或修改模型默认激活状态):
# 视图代码修改
def createaccount(request):
    page = "create-account"
    form = CustomUserRegisterForm()
    
    if request.method == "POST":
        form = CustomUserRegisterForm(request.POST)
        if form.is_valid():
            # 先创建用户对象但不立即保存
            user = form.save(commit=False)
            user.is_active = True  # 激活用户,否则无法登录
            user.save()
            # 使用email和表单中的password1进行认证
            authenticated_user = authenticate(request, email=user.email, password=form.cleaned_data["password1"])
            if authenticated_user:
                login(request, authenticated_user)
                return redirect("profilesettings:profile-page")
        # 表单无效时保留错误信息,不要重新实例化表单
                        
    context = {"form": form, "page": page}
    return render(request, "generalpage/create_account.html", context)

3. 修正管理器参数顺序

create_superuser调用create_user时,参数顺序要和create_user的定义一致(email在前,username在后):

# 管理器代码修改
class CustomUserRegisterManager(BaseUserManager):
    # ... 保留create_user方法不变
    
    def create_superuser(self, email, username, password, **extra_fields):
        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(_('Superanvändare måste ha is_staff=True.'))
        if extra_fields.get('is_superuser') is not True:
            raise ValueError(_('Superanvändare måste ha is_superuser=True.'))
        if extra_fields.get('is_active') is not True:
            raise ValueError(_('Superanvändare är inte aktiv'))
        
        # 修正参数顺序:email, username, password
        return self.create_user(email, username, password, **extra_fields)

4. 可选:修改模型默认激活状态

如果希望用户注册后直接激活,可修改模型中is_active的默认值:

# 模型代码修改
class UserRegister(AbstractBaseUser, PermissionsMixin):
    # ... 其他字段不变
    is_active = models.BooleanField(default=True)  # 改为默认激活

内容的提问来源于stack exchange,提问作者AJJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 22:20:32