Some pertinent definitions occur in django/forms/forms.py
. They are:
class BaseForm
class Form
class DeclarativeFieldsMetaclass
def get_declared_fields
get_declared_fields
is called from DeclarativeFieldsMetaclass
and constructs a list with the field instances sorted by their creation counter. It then prepends fields from the base classes to this list and returns the result as an OrderedDict
instance with the field name serving as the keys. DeclarativeFieldsMetaclass
then sticks this value in the attribute base_fields
and calls to type
to construct the class. It then passes the class to the media_property
function in widgets.py
and attaches the return value to the media
attribute on the new class.
media_property
returns a property method that reconstructs the media declarations on every access. My feeling is that it wont be relevant here but I could be wrong.
At any rate, if you are not declaring a Media
attribute (and none of the base classes do) then it only returns a fresh Media
instance with no arguments to the constructor and I think that monkeypatching a new field on should be as simple as manually inserting the field into base_fields
.
ContactForm.another_field = forms.CharField(...)
ContactForm.base_fields['another_field'] = ContactForm.another_field
Each form instance then gets a deepcopy
of base_fields
that becomes form_instance.fields
in the __init__
method of BaseForm
. HTH.