gpt4 book ai didi

python - 如何根据 James Bennett 的文章 "So you want a dynamic form"动态创建 ModelForm?

转载 作者:太空宇宙 更新时间:2023-11-04 01:34:44 24 4
gpt4 key购买 nike

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”一起使用)

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)

奖励问题:

为什么 Bennett 使用 forms.BaseForm 而不是 forms.Form 创建一个 ContactForm? (我假设这就是为什么这些字段也被称为 base_fields 的原因。)

最佳答案

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 有一个自定义元类 DeclarativeFieldsMetaclass,如果您在 中使用 Form,它会自动收集以声明语法编写的表单字段type(),看起来像(以 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)

关于python - 如何根据 James Bennett 的文章 "So you want a dynamic form"动态创建 ModelForm?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10843733/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com