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

Django AuthenticationForm校验不通过 非超级用户无法登录问题

问题根因

核心故障点在自定义注册表单UserCreateForm的save方法,super()调用参数错误,直接跳过了UserCreationForm内置的密码哈希逻辑:

  • 代码中super(UserCreationForm, self).save(commit=False)的写法,会直接调用UserCreationForm的父类ModelForm的save方法,该方法仅处理模型原生字段,不会识别password1/password2这类表单自定义字段,也不会执行密码哈希操作,最终导致通过注册页面创建的普通用户,数据库中存储的密码为空或未哈希明文,完全不符合Django的密码校验规则。
  • 超级用户通过python manage.py createsuperuser命令创建,密码会被自动哈希存储,因此可以正常通过登录校验;普通注册用户密码存储不符合规范,登录时AuthenticationForm调用认证后端校验密码失败,会直接抛出“Please enter a correct username and password”错误,无法进入form.is_valid()的通过分支。

代码中还存在两处不规范问题:

  • 注册视图GET分支写为form=UserCreateForm,未加括号实例化,传递给模板的是表单类而非实例,会引发表单渲染异常。
  • 登录视图中AuthenticationForm校验通过后又手动调用一次authenticate()属于冗余逻辑,AuthenticationForm在校验阶段已经完成了用户认证流程,可直接获取已认证的用户对象。
修复方案
  1. 修正UserCreateForm中super()的调用参数,确保正确调用父类UserCreationForm的save方法,自动完成密码哈希。
  2. 修正注册视图GET分支的表单实例化语法。
  3. 移除登录视图中的冗余认证逻辑,简化代码。
修正后的完整代码
def log_in(request):
    if request.method == "POST":
        form = AuthenticationForm(request, data=request.POST)
        if form.is_valid():
            # AuthenticationForm校验通过后可直接获取已认证用户,无需重复调用authenticate
            user = form.get_user()
            login(request, user)
            messages.info(request, 'You have successfully logged in!')
            return redirect('news')
        else:
            messages.error(request, 'Invalid username or password!')
    else:
        # GET请求初始化空表单
        form = AuthenticationForm()
    return render(request, 'post/login.html', {'form': form})


def register_user(request):
    if request.method == 'POST':
        form = UserCreateForm(request.POST)
        if form.is_valid():
            user = form.save()
            login(request, user)
            messages.success(request, 'Registration was successful')
            return redirect('news')
        messages.error(request, 'Try again!')
    else:
        # GET请求实例化空表单,必须加括号
        form = UserCreateForm()
    return render(request, 'post/register.html', {'form': form})


class UserCreateForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']

    def save(self, commit=True):
        # 修正super第一个参数为当前类名,正确调用UserCreationForm的save逻辑完成密码哈希
        user = super(UserCreateForm, self).save(commit=False)
        user.email = self.cleaned_data.get('email')
        if commit:
            user.save()
        return user

注意:代码修复前已经注册的普通用户,因为密码存储格式错误无法自动修复,需要重新注册后才能正常登录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:03:15