0

私がそのようなフォームを持っているとしましょう:

class ChangeParentCIForm(ModelForm):
    class Meta:
        model = CINodeInventory
        fields = ('parent',)
        widgets = {'parent': AutocompleteWidget('inventory.uuid'),}

問題は、私の場合、AutocompleteWidget コンテンツは、「親」フィールドの値だけでなく、ユーザー セッション情報 (別のページでユーザーが選択したデータベースのバージョン番号) のコンテキストにも依存する必要があることです。

そうするために、私はクラスベースのビューに次のようなことをしました:

class CompanyManageChangeParentCIView(CompanySelectedMixin,CIContextMixin,CompanyViewCIMixin,UpdateView):    
    template_name = 'inventory/browse_change_parent_ci.html'
    context_object_name = 'ci'
    form_class = ChangeParentCIForm

    def get_form(self,form_class):
        form = super(CompanyManageChangeParentCIView,self).get_form(form_class)
        form.base_fields['parent'].widget.url_params={'version':self.request.session['use_version']}
        return form

もちろん、この 'url_params' 追加パラメーターを処理するように AutocompleteWidget コードを変更しました。

それは機能しますが、このコードは、初期化時に生成されるフィールドの初期化時に作成されたウィジェットを変更するため、私にはあまり美しくはありません。別の言葉で、2 つのフォーム インスタンスを作成した場合、同じフィールドとウィジェットを指すので、これを行うと:

def get_form(self,form_class):
    form1 = super(CompanyManageChangeParentCIView,self).get_form(form_class)
    form2 = super(CompanyManageChangeParentCIView,self).get_form(form_class)
    form1.base_fields['parent'].widget.url_params="val1"
    form2.base_fields['parent'].widget.url_params="val2"
    print id(form1),id(form1.base_fields['parent'].widget)
    print id(form2),id(form2.base_fields['parent'].widget)

form1 と form2 が異なるインスタンスを参照していることがわかりますが、同じウィジェット (および ID を出力する場合は同じフィールド) を指しています。したがって、私の場合、form1 と form2 を同じテンプレートに表示すると、「AutocompleteWidget」という 2 つのウィジェットが表示されますが、どちらも最新の変更、つまり url_parms="val2" でカスタマイズされています。

1 つのフォームを表示しても、非常に危険に思えます。2 つのスレッドが同じウィジェットに対して 2 つの異なる「url_params」値を使用して同じコードを実行するとどうなりますか?

ここに私の質問があります:関連するフィールド値だけでなく、コンテキスト情報を使用してdjangoウィジェットのレンダリングをカスタマイズする方法は?

4

1 に答える 1

2

form.base_fieldsクラスのすべてのインスタンスで共有される を変更しているためです。form.fieldsインスタンス固有の を変更してください。

スタイルの問題として__init__、フォーム自体のメソッドでこれを行い、URL パラメーターをフォーム kwarg として渡すことをお勧めします。ビューのget_form_kwargsメソッドをオーバーライドしてそれを行うことができるように見えますが、その必要はありません。全然変わりget_formます。

于 2013-03-28T09:49:10.263 に答える