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

Django自定义用户模型登录失败问题求助

Django自定义用户模型登录失效问题修复

核心问题分析

  1. 登录表单误用ModelForm触发唯一性校验:MyUserLoginForm继承自ModelForm,而MyUser的username字段设为unique=True,ModelForm会自动执行模型字段的唯一性校验,提交登录表单时会触发「该用户名已存在」的错误,完全不符合登录场景需求。
  2. authenticate函数参数错误:Django的authenticate默认仅需username和password参数(你的USERNAME_FIELD已设为username),额外传入的email和organisation会被忽略,直接导致认证失败。
  3. 登录重定向地址配置错误:LOGIN_REDIRECT_URL设为登录页面,登录成功后会循环跳回登录页,让用户误以为登录未生效。
  4. 登录表单包含冗余字段:登录不需要email和organisation字段,多余字段既增加用户输入负担,还可能引入不必要的校验问题。
  5. 类视图继承顺序错误: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 23:13:29