Django登录功能异常:form.is_valid()返回False且无cleaned_data属性
解决你的Django登录表单问题
你的登录功能遇到的两个问题,都是由表单实例化方式错误和clean方法实现不规范导致的,我来帮你逐个梳理修复:
问题1:form.is_valid()返回False & 表单传参错误
你的LoginForm自定义了__init__方法,第一个参数是request,但视图里实例化表单时的传参逻辑完全错了,导致表单根本没拿到正确的POST数据,自然验证失败。
修复视图中的表单实例化
1. 修正LoginView的get方法
get请求是用来展示空表单的,不需要传request.POST,而且要正确传递request参数给表单:
def get(self, request): form = forms.LoginForm(request) # 只传request,不要带POST数据 return render(request, "users/login.html", {"form": form})
2. 修正LoginView的post方法
post请求需要把request作为第一个参数,同时用data关键字传递POST数据:
def post(self, request): form = forms.LoginForm(request, data=request.POST) # 正确传参:request + POST数据 print(form.is_valid()) if form.is_valid(): email = form.cleaned_data.get("email") password = form.cleaned_data.get("password") get_user = user_models.User.objects.get(email=email) # 注意:authenticate的username参数需要传入用户名字符串,不是User对象 user = authenticate(request, username=get_user.username, password=password) if user is not None: login(request, user) return redirect(reverse("cores:home")) return render(request, "users/login.html", {"form": form})
问题2:'LoginForm' object has no attribute 'cleaned_data'
这个错误是因为你的clean方法没有正确返回cleaned_data。Django要求表单的clean方法必须返回处理后的cleaned_data,否则框架不会为表单设置这个属性。
修复LoginForm的clean方法
def clean(self): # 先获取父类处理后的cleaned_data,后续操作基于这个对象 cleaned_data = super().clean() email = cleaned_data.get("email") password = cleaned_data.get("password") # 如果前面的字段验证已经失败(比如邮箱格式错误),直接返回,无需继续验证 if not email or not password: return cleaned_data try: user = models.User.objects.get(email=email) if not user.check_password(password): self.add_error("password", forms.ValidationError("비밀번호가 틀렸습니다.")) except models.User.DoesNotExist: self.add_error("email", forms.ValidationError("존재하지 않는 계정입니다.")) # 无论验证是否通过,必须返回cleaned_data return cleaned_data
总结修改点
- 修正视图中表单的实例化逻辑,正确传递
request和data参数 - 规范
clean方法的返回值,确保始终返回cleaned_data - 修复
authenticate方法的参数错误(传入用户名字符串而非User对象)
完成这些修改后,你的登录表单应该就能正常完成验证,并且cleaned_data属性也能正确获取了。
内容的提问来源于stack exchange,提问作者dhooonk
相关产品推荐
相关产品推荐

