自定义UserRegister模型注册用户时触发KeyError('password')问题
自定义UserRegister模型注册时KeyError('password')问题解决
问题现象
使用自定义UserRegister模型注册新用户时,触发KeyError: 'password',后台已成功创建用户,但无法实现注册后自动登录。
错误原因
- 表单配置冲突:
CustomUserRegisterForm继承自UserCreationForm,但在Meta中排除了password字段,导致表单验证后cleaned_data中没有password键,视图中尝试获取form.cleaned_data["password"]直接触发KeyError。 - 认证逻辑不匹配自定义模型:自定义用户模型的
USERNAME_FIELD设置为email,但视图中仍用username进行认证,不符合Django自定义用户的认证规则。 - 管理器方法参数顺序错误:
create_superuser调用create_user时参数顺序颠倒,把username放在了email的位置,会导致创建超级用户时参数传递错误。 - 用户默认未激活:模型中
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
相关产品推荐
相关产品推荐

