如何根据James Bennett的文章“soyouwantwaindadynamicform”动态创建一个模型表单?

2024-04-29 19:15:05 发布

您现在位置:Python中文网/ 问答频道 /正文

在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与内部类“Meta”一起使用)

^{pr2}$

其中include_fields是我要显示的字段元组。在

然而,即使我写了一个正确的make_order_edit_form,我如何在views.py中使用它?具体来说,我如何将POST请求和order实例都传递给它?通常我会做一些

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

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

额外问题:

为什么贝内特用forms.BaseForm而不是forms.Form创建{}?{cdm>为什么也叫cdm}


Tags: formfieldsmaketype文章orderformspost
1条回答
网友
1楼 · 发布于 2024-04-29 19:15:05

make_order_edit_form返回一个ModelForm类,因此您可以

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

对于附加问题,请检查Form代码:

^{pr2}$

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

更新

使用type来构建ModelForm,没有什么不同

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)

相关问题 更多 >