Django自定义用户模型登录失败问题求助
Django自定义用户模型登录失效问题修复
核心问题分析
- 登录表单误用ModelForm触发唯一性校验:
MyUserLoginForm继承自ModelForm,而MyUser的username字段设为unique=True,ModelForm会自动执行模型字段的唯一性校验,提交登录表单时会触发「该用户名已存在」的错误,完全不符合登录场景需求。 authenticate函数参数错误:Django的authenticate默认仅需username和password参数(你的USERNAME_FIELD已设为username),额外传入的email和organisation会被忽略,直接导致认证失败。- 登录重定向地址配置错误:
LOGIN_REDIRECT_URL设为登录页面,登录成功后会循环跳回登录页,让用户误以为登录未生效。 - 登录表单包含冗余字段:登录不需要
email和organisation字段,多余字段既增加用户输入负担,还可能引入不必要的校验问题。 - 类视图继承顺序错误:
Create_Accounts中LoginRequiredMixin放在CreateView之后,会导致登录验证逻辑不生效。
代码修复
1. 修正forms.py:替换登录表单为普通Form
class MyUserForm(forms.ModelForm): class Meta(): model = models.MyUser fields = ('username','email','password','organisation') # 补充:ModelForm需手动处理密码哈希,避免明文存储 def save(self, commit=True): user = super().save(commit=False) user.set_password(self.cleaned_data["password"]) if commit: user.save() return user # 替换原登录表单为普通Form,仅保留必要字段 class MyUserLoginForm(forms.Form): username = forms.CharField(label="用户名") password = forms.CharField(label="密码", widget=forms.PasswordInput)
2. 修正views.py:调整登录逻辑与类继承顺序
class indexPage(TemplateView): template_name = 'accounts/inner_index.html' class Create_Organisation(CreateView): model = models.Organisation fields = ('__all__') template_name = 'accounts/organisation_form.html' success_url = reverse_lazy("accounts:inner_index") # 修正继承顺序:LoginRequiredMixin需放在CreateView之前 class Create_Accounts(LoginRequiredMixin, CreateView): model = models.MyUser form_class = forms.MyUserForm template_name = 'accounts/create_account.html' success_url = reverse_lazy("accounts:inner_index") class LoginPageView(View): template_name = 'accounts/login_account.html' form_class = forms.MyUserLoginForm def get(self, request): form = self.form_class() message = '' return render(request, self.template_name, context={'form': form, 'message': message}) def post(self, request): form = self.form_class(request.POST) if form.is_valid(): # 仅传入authenticate需要的username和password参数 user = authenticate( username=form.cleaned_data['username'], password=form.cleaned_data['password'], ) if user: login(request, user) return redirect(reverse_lazy("accounts:inner_index")) message = '登录失败!请检查用户名或密码' return render(request, self.template_name, context={'form': form, 'message': message})
3. 修正settings.py:调整登录重定向地址
AUTH_USER_MODEL = 'accounts.MyUser' # 登录成功后跳转到主页,避免循环重定向 LOGIN_REDIRECT_URL = '/accounts/'
4. 优化login_account.html(可选)
新的登录表单仅包含用户名和密码,原模板的bootstrap_form会自动适配,若需更简洁可手动渲染:
{% extends 'base.html' %} {% load bootstrap3 %} {% block body_block %} <form method="POST"> <h1>登录</h1> {% csrf_token %} {% bootstrap_form form %} <input type="submit" value="登录"> </form> {% endblock %}
额外注意事项
- 密码哈希处理:原
MyUserForm未处理密码哈希,会导致密码明文存储,登录时authenticate无法匹配,因此在表单中补充了save方法处理哈希。 - 超级用户创建逻辑:
MyUserManager的create_superuser方法未设置organisation,但MyUser的organisation字段设为null=True,暂时无问题;若后续需强制超级用户关联组织,需修改该方法。
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

