Django Stale模型对象和表单ChoiceField与ModelChoiceField

时间:2013-09-06 02:25:38

标签: django django-forms

这只是一种让我烦恼的好奇心。我创建了一个Form类来处理数据库中的文档选择。当然,必须从数据库中获取文档列表以填充可用选项。我通过手动构建选项并使用ChoiceField获得“陈旧”行为。但是当我使用ModelChoiceField选项“queryset”时,我得到了准确的结果。

“陈旧”是指如果我上传新文档并呈现页面,则列表仅显示旧文档集(有时甚至在刷新页面后仍然存在,根据视图逻辑应该重新生成表单 - 这是第二种方法无论用例如何都能按预期工作的事实。 示例如下:

陈旧版本:

class GetDocumentForm(forms.Form):
    document_query   = Document.objects.all().order_by('docfile')
    document_choices = []

    for document in document_query:
        document_choices.append((document.id, document.docfile.name))

    document         = forms.ChoiceField(label='', choices=document_choices)

准确版本:

class GetDocumentForm(forms.Form):
    document         = forms.ModelChoiceField(queryset=Document.objects.all())

是什么给出的?有什么不同?他们为什么表现不同?

1 个答案:

答案 0 :(得分:3)

  

过时的版本类体应该在__init__方法内! - mariodev

谢谢mariodev。

在此之后,我能够生成正常运行的代码。我的第一次尝试仍未能正常工作:

class GetDocumentForm(forms.Form):
    def __init__(self):
        ...
        self.base_fields['document'].choices = self.document_choices[:]

这将允许我创建一个表单,但是当我尝试渲染时:

In [1]: from WebSite.forms import *

In [2]: doc_form = GetDocumentForm()

In [3]: print doc_form.as_p()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

AttributeError: 'GetDocumentForm' object has no attribute '_errors'

解决方案在这里:StackOverflow -- Django: Overloading init for Custom Forms。你需要超级班。

最终,工作代码:

class GetDocumentForm(forms.Form):
    document          = forms.ChoiceField()

    def __init__(self, *args, **kwargs):
        super(GetDocumentForm, self).__init__(*args, **kwargs)

        for doc in Document.objects.all().order_by('docfile'):
            self.fields['document'].choices.append((doc.id, doc.docfile.name))

显然使用ModelChoiceField(queryset=Document.objects.all())更加简洁。但关键是要了解如何让它以两种方式运作。

干杯。