[英]Django form.is_valid() cleans needed values
I am practicing Django, and I have been stuck on this for a while now. 我正在练习Django,现在已经坚持了一段时间。 I am trying to write a basic survey app.
我正在尝试编写一个基本的调查应用程序。 My issue is that when I submit my form, I can see that
request.POST
contains the data I need, form.data
also contains it, but after I run form.is_valid()
, I am left with only the keys in the dict, no values. 我的问题是,当我提交表单时,我可以看到该
request.POST
form.data
包含了我需要的数据, form.data
也包含了它,但是在运行form.is_valid()
,我只剩下字典中的键,没有值。
class SurveyForm(forms.Form):
def __init__(self, *args, **kwargs):
questions = kwargs.pop('questions')
super(SurveyForm, self).__init__(*args, **kwargs)
for q in questions:
choices = []
for answer in q.choice_set.all():
choices.append((answer.pk, answer.choice_text))
self.fields[q.id] = forms.ChoiceField(label=q.question_text, required=False,
choices=choices, widget=forms.RadioSelect)
def answers(self):
for q, a in self.cleaned_data.items():
yield a
If I remove required=False
, I keep getting This field is required
although, I believe it's due to the validation, because it looks like the page refreshes when I hit submit, while if I actually leave the choices blank, it doesn't refresh and instead a small popup appears above the label. 如果我删除了
required=False
,那么我一直保持This field is required
尽管我认为这是由于验证所致,因为当我单击“提交”时,页面看起来像在刷新,而如果我将选项保留为空白,则不会刷新而是在标签上方显示了一个小弹出窗口。
Here is the view that uses it. 这是使用它的视图。
def step(request, survey_id, attempt_id, surveypage_nr):
survey = get_object_or_404(Survey, pk=survey_id)
attempt = get_object_or_404(Attempt, pk=attempt_id)
pages = survey.surveypage_set.all().order_by('page_nr')
page = pages.filter(page_nr=surveypage_nr).first();
questions = page.question_set.all()
form = SurveyForm(request.POST or None, questions=questions)
if form.is_valid():
for a in form.answers():
answer = get_object_or_404(Choice, pk=a)
attempt.score = attempt.score + answer.score
attempt.save()
return HttpResponseRedirect(reverse('results', args=(survey.id, attempt.id,)))
else:
context = {'page': page, 'form': form}
return render(request, 'survey/surveypage.html', context)
I tried checking the contents of the form after the is_valid()
call: 我尝试在
is_valid()
调用之后检查表单的内容:
request.POST = {'3': '2', '4': '3', 'csrfmiddlewaretoken': 'f..m1'}
form.data = {'3': '2', '4': '3', 'csrfmiddlewaretoken': 'f..m1'}
form.cleaned_data = {3: '', 4: ''}. # Why are you cleaning my values, Django?
form.fields = OrderedDict([(3, <django.forms.fields.ChoiceField object at 0x106c2d5f8>),
(4, <django.forms.fields.ChoiceField object at 0x1055ebba8>)])
As you can see, request.POST
and form.data
contain exactly what I need, but after validation, form.cleaned_data
doesn't have values for the keys. 如您所见,
request.POST
和form.data
完全包含我所需要的内容,但是在验证之后, form.cleaned_data
没有键的值。 Why is this happening? 为什么会这样呢? Help pls.
帮助请。
form.cleaned_data
的键是string,而form.data
是int。
As the other answer pointed out, the key needs to be a string. 正如另一个答案指出的那样,密钥必须是字符串。 Data in a POST is always a string, but your keys are currently int.
POST中的数据始终是字符串,但是您的密钥当前为int。 So when Django goes to validate the data for field
'3'
it finds nothing, so shows it as empty; 因此,当Django验证字段
'3'
的数据时,它什么也没找到,因此将其显示为空。 meanwhile it doesn't have a field called 3
so throws away that key/value. 同时,它没有名为
3
的字段,因此会丢弃该键/值。
You should set your field IDs to strings: 您应该将字段ID设置为字符串:
self.fields[str(q.id)] = ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.