2

これは私を悩ませている単なる好奇心です。データベースからのドキュメントの選択を処理する Form クラスを作成しました。当然、データベースからドキュメントのリストを取得して、利用可能な選択肢を設定する必要があります。選択肢を手動で作成し、ChoiceField を使用すると、「古い」動作が発生します。しかし、ModelChoiceField オプション "queryset" を利用すると、正確な結果が得られます。

「古い」とは、新しいドキュメントをアップロードしてページをレンダリングすると、古いドキュメント セットのみがリストに表示されることを意味します (ページの更新後も保持される場合があり、ビュー ロジックに従ってフォームを再生成する必要があります)。これは、ユースケースに関係なく、2 番目の方法が期待どおりに機能するという事実です)。例は次のとおりです。

古いバージョン:

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())

何を与える?違いは何ですか?なぜ彼らは異なる振る舞いをするのですか?

4

1 に答える 1

3

古いバージョンのクラス本体は__init__メソッド内にある必要があります! –マリオデフ

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))

明らかに、 usingModelChoiceField(queryset=Document.objects.all())の方がはるかに簡潔です。しかし、ポイントは、それを両方の方法で機能させる方法を理解することでした.

乾杯。

于 2013-09-06T18:39:52.483 に答える