23

ビューから ModelForm のインライン Meta クラスを動的に更新したいと考えています。このコードは Meta クラスの除外リストを更新しているように見えますがas_p()as_ul()、 などからの出力は、更新された Meta 除外を反映していません。

as_*()が呼び出されたときではなく、ModelForm が作成されたときに html が生成されると仮定します。HTML を強制的に更新する方法はありますか?

これはそれを行うための最良の方法ですか?私はこれがうまくいくはずだと思っただけです。

考え?

from django.forms import ModelForm

from testprogram.online_bookings.models import Passenger

class PassengerInfoForm(ModelForm):

    def set_form_excludes(self, exclude_list):
        self.Meta.exclude = excludes_list

    class Meta:
        model = Passenger
        exclude = []
4

4 に答える 4

59

Meta クラスは、フォーム定義を動的に構築するために使用されます。したがって、ModelForm インスタンスを作成するまでに、除外に含まれていないフィールドは、新しいオブジェクトの属性として既に追加されています。

これを行う通常の方法は、可能な除外リストごとに複数のクラス定義を用意することです。ただし、フォーム自体を動的にしたい場合は、その場でクラス定義を作成する必要があります。何かのようなもの:

def get_form(exclude_list):
    class MyForm(ModelForm):
        class Meta:
            model = Passenger
            exclude = exclude_list
    return MyForm

form_class = get_form(('field1', 'field2'))
form = form_class()

更新:私はこの投稿を再訪し、動的クラスを処理するためのもう少し慣用的な方法を投稿すると思いました:

def PassengerForm(exclude_list, *args, **kwargs):
    class MyPassengerForm(ModelForm):
        class Meta:
            model = Passenger
            exclude = exclude_list

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

    return MyPassengerForm()

form = PassengerForm(('field1', 'field2'))
于 2008-11-18T00:38:08.247 に答える
13

別の方法:

class PassengerInfoForm(ModelForm):
    def __init__(self, *args, **kwargs):
        exclude_list=kwargs.pop('exclude_list', '')

        super(PassengerInfoForm, self).__init__(*args, **kwargs)

        for field in exclude_list:
            del self.fields[field]

    class Meta:
        model = Passenger

form = PassengerInfoForm(exclude_list=['field1', 'field2'])
于 2009-04-01T02:54:06.560 に答える
4

同様のアプローチ、多少異なる目標 (任意のモデルの一般的な ModelForm):

from django.contrib.admin.widgets import AdminDateWidget
from django.forms import ModelForm
from django.db import models

def ModelFormFactory(some_model, *args, **kwargs):
    """
    Create a ModelForm for some_model
    """
    widdict = {}
    # set some widgets for special fields
    for field in some_model._meta.local_fields:
        if type(field) is models.DateField:
            widdict[field.name] = AdminDateWidget()

    class MyModelForm(ModelForm): # I use my personal BaseModelForm as parent
        class Meta:
            model = some_model
            widgets = widdict

    return MyModelForm(*args, **kwargs)
于 2010-10-01T16:02:02.880 に答える
3

使用modelform_factory(ドキュメント):

from django.forms.models import modelform_factory

from testprogram.online_bookings.models import Passenger

exclude = ('field1', 'field2')
CustomForm = modelform_factory(model=Passenger, exclude=exclude)  # generates ModelForm dynamically
custom_form = CustomForm(data=request.POST, ...)  # form instance
于 2015-11-13T02:31:33.093 に答える