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

Django认证表单提交始终无效问题排查求助

Django表单验证失败问题解决

问题根源拆解

  1. 表单未获取用户提交的数据:你在request.POST分支里,仅创建了空的RegisterForm实例,完全没把用户提交的POST数据传入。空表单必然通不过验证,这就是一直走not valid分支的核心原因。
  2. 注册表单未处理密码加密:当前RegisterForm没有重写save方法,即便验证通过,保存用户时密码会以明文存储,既不安全,后续登录也会失败。
  3. 视图与模板的表单变量名不匹配:视图出错时往上下文传入的是registration_form,但模板里用的是form,导致错误信息无法展示,你根本不知道验证失败的具体原因。

修复代码

1. 修正views.py

def index(request):
    if request.method == 'POST':
        print('post')
        # 关键:用POST数据初始化表单,让表单获取用户输入
        form = forms.RegisterForm(request.POST)
        if form.is_valid():
            print('valid')
            user = form.save()
            email = form.cleaned_data.get('email')
            raw_password = form.cleaned_data.get('password')
            account = authenticate(email=email, password=raw_password)
            print('authenticate')
            login(request, account)
            return redirect('home')
        else:
            print('not valid')
            # 保持变量名与模板一致,确保错误信息能正常显示
            context = {'form': form}
    else:
        # GET请求时创建空表单
        form = forms.RegisterForm()
        context = {'form': form}

    return render(request, 'index.html', context)

2. 完善forms.py中的RegisterForm

给RegisterForm添加密码加密和全名保存逻辑:

class RegisterForm(forms.ModelForm):
    """
    用户注册表单
    """
    full_name = forms.CharField(max_length=30)
    password = forms.CharField(widget=forms.PasswordInput)
    password_2 = forms.CharField(label='确认密码', widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ['email']

    def clean_email(self):
        '''
        验证邮箱是否已被注册
        '''
        email = self.cleaned_data.get('email')
        if User.objects.filter(email=email).exists():
            raise forms.ValidationError("该邮箱已被使用")
        return email

    def clean(self):
        '''
        验证两次输入的密码是否一致
        '''
        cleaned_data = super().clean()
        password = cleaned_data.get("password")
        password_2 = cleaned_data.get("password_2")
        if password and password != password_2:
            self.add_error("password_2", "两次密码输入不一致")
        return cleaned_data

    # 添加save方法,处理密码加密和全名保存
    def save(self, commit=True):
        # 先不提交到数据库
        user = super().save(commit=False)
        # 对密码进行加密处理
        user.set_password(self.cleaned_data["password"])
        # 把full_name赋值给用户模型(需确保你的User模型有full_name字段)
        user.full_name = self.cleaned_data['full_name']
        if commit:
            user.save()
        return user

3. 模板优化(可选)

在模板表单上方添加错误信息展示,方便调试:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用户注册</title>
</head>
<body>
    <!-- 显示表单错误信息 -->
    {% if form.errors %}
        <div style="color: red;">
            {% for field in form %}
                {% for error in field.errors %}
                    <p>{{ field.label }}: {{ error }}</p>
                {% endfor %}
            {% endfor %}
            {% for error in form.non_field_errors %}
                <p>{{ error }}</p>
            {% endfor %}
        </div>
    {% endif %}

    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">提交注册</button>
    </form>
</body>
</html>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 08:03:32