给出一个表单类(在你的巨型Django应用程序的某个深处)..
class ContactForm(forms.Form):
name = ...
surname = ...
考虑到你想在没有扩展或修改表单类本身的情况下向该表单添加另一个字段,为什么以下方法不起作用?
ContactForm.another_field = forms.CharField(...)
(我的第一个猜测是,Django使用的元类hackery仅在第一次构造表单类时应用。如果是这样,是否有办法重新声明类以克服这个问题?)
答案 0 :(得分:8)
django/forms/forms.py
中出现了一些相关的定义。他们是:
class BaseForm
class Form
class DeclarativeFieldsMetaclass
def get_declared_fields
get_declared_fields
调用 DeclarativeFieldsMetaclass
并构造一个列表,其中的字段实例按其创建计数器排序。然后,它会将基类中的字段预先添加到此列表中,并将结果作为OrderedDict
实例返回,并将字段名称作为键。 DeclarativeFieldsMetaclass
然后将此值粘贴到属性base_fields
中,并调用type
来构造类。然后它将类传递给media_property
中的widgets.py
函数,并将返回值附加到新类的media
属性。
media_property
返回一个属性方法,该方法在每次访问时重建媒体声明。我的感觉是它不相关,但我可能错了。
无论如何,如果你没有声明一个Media
属性(并且没有任何基类这样做),那么它只会返回一个没有构造函数参数的新Media
实例,我认为monkeypatching一个新字段应该像手动将字段插入base_fields
一样简单。
ContactForm.another_field = forms.CharField(...)
ContactForm.base_fields['another_field'] = ContactForm.another_field
然后,每个表单实例获得deepcopy
base_fields
form_instance.fields
__init__
BaseForm
方法{{1}}。 HTH。