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

Django自定义AuthenticationForm传LoginView出现多余输入框问题

问题原因

django.contrib.auth.forms.AuthenticationForm 本身是继承自基础Form类的普通表单,不是ModelForm,所以你在子类里写的class Meta配置(包括model、fields属性)不会生效。
这个父类默认硬编码了username字段作为登录标识字段,你在子类里额外新增email字段后,表单实例一共会包含username、email、password三个字段,模板循环渲染时自然会多出一个输入框。

修复步骤

1. 修正表单代码

首先移除父类自带的username字段,同时重写表单校验逻辑,把输入的邮箱作为认证参数传给认证系统,替换默认的用户名校验逻辑:

from django.contrib.auth.forms import AuthenticationForm
from django import forms
from django.contrib.auth import authenticate

class AccountSignInForm(AuthenticationForm):
    # 移除父类默认的username字段
    username = None
    email = forms.EmailField(
        widget=forms.EmailInput(attrs={'placeholder': 'E-Mail..'}),
        label='E-Mail'
    )
    password = forms.CharField(
        widget=forms.PasswordInput(attrs={'placeholder': 'Password..'}),
        label='Password'
    )

    def clean(self):
        email = self.cleaned_data.get('email')
        password = self.cleaned_data.get('password')

        if email and password:
            # 把邮箱作为认证用户名参数传入
            self.user_cache = authenticate(
                self.request,
                username=email,
                password=password
            )
            if self.user_cache is None:
                raise self.get_invalid_login_error()
            self.confirm_login_allowed(self.user_cache)
        return self.cleaned_data

2. 配置邮箱认证逻辑(如果未配置)

如果你的Account自定义用户模型没有将USERNAME_FIELD设置为email,需要额外新增邮箱认证后端,否则表单提交时会找不到对应用户:

  • 新建accounts/backends.py文件:
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend

class EmailAuthBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        User = get_user_model()
        try:
            user = User.objects.get(email=username)
        except User.DoesNotExist:
            return None
        if user.check_password(password) and self.user_can_authenticate(user):
            return user
        return None
  • 在项目settings.py中注册认证后端:
AUTHENTICATION_BACKENDS = [
    'accounts.backends.EmailAuthBackend',
    'django.contrib.auth.backends.ModelBackend',
]

3. 修正视图层配置

你原有代码里的success_url直接传字符串'HomePageView'无法正常解析跳转,需要用reverse_lazy指向对应命名路由:

from django.contrib.auth.views import LoginView
from django.urls import reverse_lazy
from .forms import AccountSignInForm

class AccountLoginView(LoginView):
    template_name = 'accounts/login.html'
    form_class = AccountSignInForm
    # 替换为你自己首页的路由命名
    success_url = reverse_lazy('home')

4. 模板无需修改

原有模板循环渲染表单字段的逻辑会自动过滤掉被置为None的username字段,最终页面只会保留E-Mail、Password两个输入框。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 22:42:23