【发布时间】:2018-02-05 05:11:54
【问题描述】:
我有一个注册表单,它包含所有常见的东西,但有一个机器人预防功能。我制作了一个模型 SecurityQuestion,它包含两个字符域,问题和答案。在注册期间,其中一个是随机挑选的,应该将答案传递给表格,以便在那里进行验证。但是,由于我尚未弄清楚的原因,它似乎没有将答案传递给表单
让我们从代码开始
profile/forms.py
# FORM: Register an account
class UserRegistrationFirstForm(forms.ModelForm):
username = forms.CharField(max_length=20)
password = forms.CharField(widget=forms.PasswordInput)
password_confirm = forms.CharField(widget=forms.PasswordInput)
email = forms.EmailField()
email_confirm = forms.EmailField()
answer = forms.CharField(max_length=50, required=True)
hidden_answer = forms.CharField(widget=forms.HiddenInput)
class Meta:
model = User
fields = [
'username',
'email',
'email_confirm',
'password',
'password_confirm',
'answer',
]
def clean_answer(self):
formated_user_answer = self.cleaned_data.get("answer").lower()
formated_hidden_answer = self.cleaned_data.get("hidden_answer").lower()
if formated_hidden_answer != formated_user_answer:
raise forms.ValidationError("Incorect answer to security question!")
return answer
如您所见,有两个字段,answer 和 hidden_answer。 answer 是用户输入答案的地方,hidden_answer 应该在初始化表单和传递 init 时填充。
profiles/views.py
# VIEW: Register an account
def custom_register(request):
if request.user.is_authenticated():
return redirect(reverse('profile', host='profiles'))
# Grab a random registration security Q&A
qa_count = SecurityQuestion.objects.count() - 1
sec_qa = SecurityQuestion.objects.all()[randint(0, qa_count)]
# Form for users to register an account
form = UserRegistrationForm(request.POST or None, initial={"hidden_answer": sec_qa.answer,})
# Validate the registration form
if form.is_valid():
# Create new account
user = form.save(commit=False)
password = form.cleaned_data.get("password")
user.set_password(password)
user.save()
# Set the default avatar
user.profile.avatar = get_default_avatar()
user.profile.save()
login(request, user)
messages.success(request, "Welcome " + user.username + ", you have successfully registered an account!")
return redirect(reverse('pages:frontpage', host='www'))
# Context dict to return for template
context = {
"title": "Registration",
"form": form,
"question": sec_qa.question,
}
return render(request, 'profiles/register.html', context)
好的,所以在注册视图中,我随机选择一个安全问题,然后将其传递给带有initial={"hidden_answer": sec_qa.answer,} 的表单。但是它似乎没有通过,因为我收到以下错误:
'NoneType' object has no attribute 'lower'
Exception Location: path/to/profiles/forms.py in clean_answer, line 103
formated_hidden_answer = self.cleaned_data.get("hidden_answer").lower()
好的,所以 NoneType 意味着没有什么可参考的。我尝试了几种不同的方法来解决这个问题。我尝试将 hidden_answer 放入表单的元字段列表中。我还在模板中尝试了{{ form.hidden_answer.as_hidden }}(这与我在这里尝试实现的完全相反,因为答案仍然显示在页面源中隐藏输入的值中)。知道我做错了什么吗?
编辑:如果我正在尝试做的事情有替代或简单的解决方案,您能否参考任何有关它的文档?
【问题讨论】:
标签: python django forms validation