12

ModelFormSetDjango アプリケーション用の csv インポート フォームを作成しており、インポートする行を検証目的で表示したいと考えています。

したがってModelAdmin、csv から行を読み取り、ModelFormSet(queryset=an_empty_queryset, initial={data_from_the_csv}).

ForeignKey問題は、モデルがフィールドを介して他の 3 つのモデルを参照し、フォームセットの各フォームの各フィールドModelChoiceFieldに対して、のオプションを入力するためにデータベース クエリが発行されることです。

Django がフォームをキャッシュしないのはなぜですか (何度か使用されているため)、またはこれを実現する方法が既にあるのでしょうか?

4

1 に答える 1

17

Django フォームセットは、フォーム作成のすべての詳細をフォーム オブジェクト自体に委譲するだけであり、個々のフォーム インスタンスは他のインスタンスを認識しないため、それぞれが独自の選択を照会する必要があることは予想外ではありません。

キャッシュには、意図しない副作用もある可能性があります。たとえば、フォームの機能が受信__init__したデータに依存し、キャッシュされたオブジェクトが正しくなくなる可能性があります。initialform

クエリの数を減らす最善の方法は、選択クエリセットを一度取得してから、コンストラクターでフォーム クラスに渡すことです。ModelFormこれには、 customとcustom を定義する必要がありますModelFormSet

フォームには、選択肢を直接受け入れるコンストラクターが必要です。

from django.forms.models import ModelForm

class MyForm(ModelForm):
    def __init__(self, my_field_choices=None, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['my_field'].choices = my_field_choices

また、フォームセットはクエリセットを実行するメソッドをオーバーライドし、作成時にフォームに渡す必要があります。

from django.forms.models import BaseModelFormSet

class MyFormSet(BaseModelFormSet):
    def _construct_forms(self):
        # instantiate all the forms and put them in self.forms
        self.forms = []

        # Define each of your choices querysets
        my_field_choices = Model.object.filter(...)

        #Add your querysets to a dict to pass to the form
        form_defaults = {'my_field_choices': my_field_choices, }

        for i in xrange(min(self.total_form_count(), self.absolute_max)):
            self.forms.append(self._construct_form(i, **form_defaults))

(これがどのように機能するかを調べるには、Django のソースを参照してください)

于 2013-03-06T15:30:55.687 に答える