需求
为了完成登录功能,我希望对id,pwd,以及验证码进行校验,所以我定义了一个LoginForm,里面有三个字段:
class LoginForm(forms.Form):
identity = forms.CharField(label="Id",required=True)
pwd = forms.CharField(label="Password", required=True)
check_code = forms.CharField(label="Check Code", required=True)
但是,在前端提交之后一直报错…
报错信息
django.core.exceptions.FieldError: Cannot resolve keyword 'check_code' into field. Choices are: account, ...
提示我check_code这个字段是不存在的。我在想,我用form是可以包含模型中没有的额外字段呀,为啥一直报错呢?
原代码
def emp_login(request):
if request.method == 'GET':
form = LoginForm()
return render(request, 'login.html', {'form': form})
form = LoginForm(data=request.POST)
if form.is_valid():
post_code = form.cleaned_data['check_code']
# 验证码错误
if post_code.upper() != request.session['image_code']:
form.add_error("check_code", "Wrong code.")
return render(request, 'login.html', {'form': form})
id_obj = models.Employee.objects.filter(identity=form.cleaned_data['identity']).first()
if not id_obj:
form.add_error("identity", "This id is not exists.")
return render(request, 'login.html', {'form': form})
# 密码错误
emp_obj = models.Employee.objects.filter(**form.cleaned_data).first()
if not emp_obj:
form.add_error("pwd", "This password is not correct.")
return render(request, 'login.html', {'form': form})
# 登陆成功
request.session["info"] = {'id': emp_obj.identity, 'name': emp_obj.name}
request.session.set_expiry(60 * 60 * 24 * 7)
return redirect('/emp/')
return render(request, 'login.html', {'form': form})
原因
后来我仔细查看我在views里面写的函数,发现我拿着cleaned_data直接当filter的条件了。(就是这个万恶的**form.cleaned_data
)
emp_obj = models.Employee.objects.filter(**form.cleaned_data).first()
之所以会这样是因为在之前我并没有添加check_code字段,所以我的cleaned_data里面是没有check_code的,可以直接用来filter,但是我加上check_code之后,我就忘记了需要在filter之前把check_code给pop出来。
修改
post_code = form.cleaned_data.pop('check_code')
只需要修改这一句就好啦,以后要记得将不是模型里面的字段给剔除才能直接用filter哇。