Python Django form.is_valid()清除所需的值

Python Django form.is_valid()清除所需的值,python,django,forms,validation,Python,Django,Forms,Validation,我正在练习Django,我已经在这上面呆了一段时间了。我正在尝试编写一个基本的调查应用程序。我的问题是,当我提交表单时,我可以看到request.POST包含我需要的数据,form.data也包含它,但在我运行form.is\u valid()之后,我只剩下dict中的键,没有值 class SurveyForm(forms.Form): def __init__(self, *args, **kwargs): questions = kwargs.pop('questi

我正在练习Django,我已经在这上面呆了一段时间了。我正在尝试编写一个基本的调查应用程序。我的问题是,当我提交表单时,我可以看到
request.POST
包含我需要的数据,
form.data
也包含它,但在我运行
form.is\u valid()
之后,我只剩下dict中的键,没有值

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
如果我删除
required=False
,我会不断得到
这个字段是必填的
,尽管我相信这是由于验证,因为当我点击submit时,页面看起来会刷新,而如果我真的将选项留空,它不会刷新,反而会在标签上方出现一个小的弹出窗口

下面是使用它的视图

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)
在调用
后,我尝试检查表单的内容

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>)])
request.POST={'3':'2','4':'3','csrfmiddlewaretoken':'f..m1'}
form.data={'3':'2','4':'3','csrfmiddlewaretoken':'f..m1'}
form.cleaned_data={3:'',4:''}.#你为什么要清洗我的价值观,Django?
form.fields=OrderedDict([(3,),
(4, )])

如您所见,
request.POST
form.data
正好包含我需要的内容,但是经过验证,
form.data
没有键的值。为什么会这样?请帮忙。

表单中的键。
清除的数据是字符串,但是
表单。数据是int。

表单中的键。
清除的数据是字符串,但是
表单。数据是int。

正如另一个答案所指出的,键需要是字符串。POST中的数据始终是字符串,但您的键当前为int。因此,当Django去验证字段
'3'
的数据时,它找不到任何内容,因此显示为空;同时,它没有一个名为
3
的字段,因此会丢弃该键/值

您应该将字段ID设置为字符串:

self.fields[str(q.id)] = ...

正如另一个答案所指出的,键必须是字符串。POST中的数据始终是字符串,但您的键当前为int。因此,当Django去验证字段
'3'
的数据时,它找不到任何内容,因此显示为空;同时,它没有一个名为
3
的字段,因此会丢弃该键/值

您应该将字段ID设置为字符串:

self.fields[str(q.id)] = ...

我完全不明白你用
答案
方法在做什么。数据直接在
self.cleaned_data
中找到,您永远不想在那里引用
self.fields
。但是如果您查看我文章的底部,您可以看到
表单。cleaned_data
不包含我需要的数据。我只访问了
form.fields
form.data
,因为我很好奇那里有什么,答案在哪里丢失了,因为我可以在
请求中看到它们。POST
。另外,为了更容易理解,我更改了
answers
方法中的最后一行。我只想用它来获取问题的答案。我可以只解析
请求。发布这些值的
,但我想学习如何正确地执行所有操作,这就是为什么我想验证表单并使用
清理的\u数据
。很抱歉,无法复制该输出。您究竟在哪里打印清洁的数据?您确定该表单上没有任何干净的方法吗?就在视图中
if form.is\u valid()语句的后面。我在那里有几张照片,包括
form.cleaned\u data
form.data
request.POST
。为了清晰起见,我在发布的代码中删除了它们,但您可以在原始帖子的最后一块中看到它们的内容。你觉得我还能帮你发点什么吗?html模板?模型?不,您看到的基本上是我的整个
表单.py
,除了导入。我没有重写任何干净的方法或任何东西。我完全不明白你在用
answers
方法做什么。数据直接在
self.cleaned_data
中找到,您永远不想在那里引用
self.fields
。但是如果您查看我文章的底部,您可以看到
表单。cleaned_data
不包含我需要的数据。我只访问了
form.fields
form.data
,因为我很好奇那里有什么,答案在哪里丢失了,因为我可以在
请求中看到它们。POST
。另外,为了更容易理解,我更改了
answers
方法中的最后一行。我只想用它来获取问题的答案。我可以只解析
请求。发布这些值的
,但我想学习如何正确地执行所有操作,这就是为什么我想验证表单并使用
清理的\u数据
。很抱歉,无法复制该输出。您究竟在哪里打印清洁的数据?您确定该表单上没有任何干净的方法吗?就在视图中
if form.is\u valid()语句的后面。我在那里有几张照片,包括
form.cleaned\u data
form.data
request.POST
。为了清晰起见,我在发布的代码中删除了它们,但您可以在原始帖子的最后一块中看到它们的内容。你觉得我还能帮你发点什么吗?html模板?模型?不,您看到的基本上是我的整个
表单.py
,除了导入。我没有重写任何干净的方法或任何东西。这应该会有帮助,具体如何?老实说,我甚至不关心键,我关心的是值,正如你所看到的,这些值以
的形式被更改为
'
。数据被清理了。
。嗯,确实是这样,但我必须给丹尼尔一个正确的答案,因为他实际上解释了发生的事情。这是人们应该看到的完整答案。谢谢你的帮助。这应该是有帮助的,具体如何?老实说,我甚至不在乎钥匙,我在乎