python - 自動 - view form django



James Bennettの記事「あなたは動的フォームが必要です」に基づいて、ModelFormを動的に作成する方法は? (1)

make_order_edit_formModelFormクラスを返します。

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は、宣言構文で書かれたフォームフィールドを自動的に収集するカスタマイズされたメタクラスDeclarativeFieldsMetaclassを持っています。もしあなたがtype()Formを使用していれば、それは見えます(Bennettの例を参照)

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 })

更新

ModelFormtypeを使って構築するには、あまり違いはありません

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)

James Bennettの記事「あなたは動的なフォームが必要です」 (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同じことをしforms.ModelFormか? forms.ModelForm

これまでのところ、私はちょうどこのようなことをやっています(内部クラス 'Meta'で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使用views.pyますか? 具体的には、POST要求と注文インスタンスの両方を渡す方法はありますか? 通常、私は次のようなことをします

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

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

ボーナスの質問:

なぜBennettはforms.BaseFormではなくforms.BaseFormからContactForm作成したのですか? (私はそれがフィールドもbase_fieldsと呼ばれる理由だと仮定しています。)





django-views