Django认证表单提交始终无效问题排查求助
Django表单验证失败问题解决
问题根源拆解
- 表单未获取用户提交的数据:你在
request.POST分支里,仅创建了空的RegisterForm实例,完全没把用户提交的POST数据传入。空表单必然通不过验证,这就是一直走not valid分支的核心原因。 - 注册表单未处理密码加密:当前
RegisterForm没有重写save方法,即便验证通过,保存用户时密码会以明文存储,既不安全,后续登录也会失败。 - 视图与模板的表单变量名不匹配:视图出错时往上下文传入的是
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
相关产品推荐
相关产品推荐

