5

私はinlineformset_factory、クライアントとセッションの間の多対多の関係のためのフィールドを作成するために使用しており、中間の出席モデルを使用しています。

ビューファイルには次のものがあります。

AttendanceFormset = inlineformset_factory(
    Session,
    Attendance,
    formset=BaseAttendanceFormSet,
    exclude=('user'),
    extra=1,
    max_num=10,
    )

session = Session(user=request.user)
formset = AttendanceFormset(request.POST, instance=session)

また、フォーム フィールドの 1 つをオーバーライドする必要があったため、フォームセットの基本クラスに以下を追加しました。

class BaseAttendanceFormSet(BaseFormSet):

    def add_fields(self, form, index):
        super(BaseAttendanceFormSet, self).add_fields(form, index)
        form.fields['client'] = forms.ModelChoiceField(
                queryset=Client.objects.filter(user=2))

これで、フォームは正しく機能しますが、ID 2 を使用するだけでなく、現在のユーザーに基づいて表示されるクライアントをフィルター処理できるように、フォームセットに値を渡す必要があります。

誰でも助けることができますか?

アドバイスをいただければ幸いです。

ありがとう。

編集

読んでいる人にとって、これは私のために働いたものです:

def get_field_qs(field, **kwargs):
        if field.name == 'client':
            return forms.ModelChoiceField(queryset=Client.objects.filter(user=request.user))
        return field.formfield(**kwargs)
4

1 に答える 1

8

formset を提供する代わりに、inlineformset_factory の formfield_callback パラメータを利用するのはどうですか? フォームで使用する必要があるフィールドを返す callable を提供します。

フォーム フィールド コールバックは、最初のパラメーターとしてフィールドを取得し、オプションのパラメーター (例: ウィジェット) の **kwargs を取得します。

例 (フィルターに request.user を使用し、必要に応じて別のものに置き換えます。

def my_view(request):
    #some setup code here

    def get_field_qs(field, **kwargs):
        formfield = field.formfield(**kwargs)
        if field.name == 'client':
            formfield.queryset = formfield.queryset.filter(user=request.user)
        return formfield

    AttendanceFormset = inlineformset_factory(
        ...
        formfield_callback=get_field_qs
        ...
    )

    formset = AttendanceFormset(request.POST, instance=session)

理解を深めるには、Django の FormSet コードでの formfield_callbackの使用法を参照してください。

于 2011-09-06T11:16:45.120 に答える