7

给定一个表单类(在你巨大的 Django 应用程序的深处)..

class ContactForm(forms.Form):
    name = ...
    surname = ...

考虑到您想在不扩展或修改表单类本身的情况下向该表单添加另一个字段,为什么以下方法不起作用?

ContactForm.another_field = forms.CharField(...)

(我的第一个猜测是 Django 使用的元类hackery 仅在第一次构造表单类时应用。如果是这样,是否有办法重新声明该类来克服这个问题?)

4

1 回答 1

9

一些相关的定义出现在django/forms/forms.py. 他们是:

  1. class BaseForm
  2. class Form
  3. class DeclarativeFieldsMetaclass
  4. def get_declared_fields

get_declared_fields从中调用DeclarativeFieldsMetaclass并构造一个列表,其中的字段实例按其创建计数器排序。然后它将基类中的字段添加到此列表中,并将结果作为OrderedDict实例返回,其中字段名称作为键。DeclarativeFieldsMetaclass然后将此值粘贴在属性中base_fields并调用type构造类。然后它将类传递给media_property函数 inwidgets.py并将返回值附加到media新类的属性上。

media_property返回一个属性方法,该方法在每次访问时重构媒体声明。我的感觉是它在这里不相关,但我可能是错的。

无论如何,如果你没有声明一个Media属性(并且没有一个基类这样做),那么它只会返回一个Media没有参数的新实例给构造函数,我认为猴子修补一个新字段应该像手动插入一样简单字段进入base_fields.

ContactForm.another_field = forms.CharField(...)
ContactForm.base_fields['another_field'] = ContactForm.another_field

然后每个表单实例都会在 的deepcopy方法中base_fields得到一个。HTH。form_instance.fields__init__BaseForm

于 2010-10-14T07:02:43.430 回答