2

James Bennett の記事「So you want a dynamic form」 (2008 年 11 月 9 日) で、彼は次のようにして動的フォームを作成できると書いています。

def make_contact_form(user):
    fields = { 'name': forms.CharField(max_length=50),
               'email': forms.EmailField(),
               'message': forms.CharField(widget=forms.Textarea) }
    if not user.is_authenticated():
        fields['captcha'] = CaptchaField()
    return type('ContactForm', (forms.BaseForm,), { 'base_fields': fields })

しかし、どうやって同じことをしforms.ModelFormますか?

これまでのところ、私はこのようなことをしているだけです(type内部クラス「メタ」での使用方法がわかりませんでした)

def make_order_edit_form(include_fields):
    class _OrderEditForm(forms.ModelForm):
        if 'fa_date' in include_fields:
            fa_date = CustomDateTimeField(label="first appointment time")

        class Meta:
            model = Order
            fields = include_fields
            widgets = custom_widgets

    return _OrderEditForm

include_fields表示したいフィールドのタプルはどこにありますか。

しかし、正しいと書いたとしてもmake_order_edit_form、どのように使用すればよいのviews.pyでしょうか? 具体的には、POST リクエストと注文インスタンスの両方を渡すにはどうすればよいですか? 通常、私は次のようなことをします

order = Order.objects.get(pk=pk)

order_form = OrderEditForm(data=request.POST, instance=order)

おまけの質問:

ベネットが の代わりにContactFormアウト を作成したのはなぜですか? (それがフィールドも呼び出される理由だと思います。)forms.BaseFormforms.Formbase_fields

4

1 に答える 1

3

make_order_edit_formクラスを返すModelFormので、次のことができます

form_cls = make_order_edit_form(fields)
order_form = form_cls(request.POST, instance=order)

おまけの質問については、Formコードを確認してください。

class Form(BaseForm):
    "A collection of Fields, plus their associated data."
    # This is a separate class from BaseForm in order to abstract the way
    # self.fields is specified. This class (Form) is the one that does the
    # fancy metaclass stuff purely for the semantic sugar -- it allows one
    # to define a form using declarative syntax.
    # BaseForm itself has no way of designating self.fields.
    __metaclass__ = DeclarativeFieldsMetaclass

には、宣言構文で記述されたフォーム フィールドを自動的に収集するカスタマイズされFormたメタ クラスがあります。DeclarativeFieldsMetaclassFormtype()

type('ContactForm', (forms.Form,), {
    'name': forms.CharField(max_length=50),
    'email': forms.EmailField(),
    'message': forms.CharField(widget=forms.Textarea)}
# instead of
type('ContactForm', (forms.BaseForm,), { 'base_fields': fields })

アップデート

ModelFormを使用して構築するtype、大した違いはありません

def make_order_edit_form(include_fields):
    d = {}
    class Meta:
        model = Order
        fields = include_fields
        widgets = custom_widgets 
    d = {'Meta':Meta}
    if 'fa_date' in include_fields:
        d['fa_date'] = CustomDateTimeField(label="first appointment time")
    return type('OrderEditForm', (forms.ModelForm,), d)
于 2012-06-01T04:59:17.303 に答える