Django AdminForm objects and templates
I can’t find documentation for the context of a Django admin template. In particular, where is the form and how does one access the fields? This post describes the template context for a generic admin model for Django 1.1.
Django uses an instance of ModelAdmin (defined in django.contrib.admin.options) to handle the request for a model object add / change view in the admin site. ModelAdmin.add_view and ModelAdmin.change_view are responsible for populating the template context when rendering the add object and change object pages respectively.
Here are the keys common to add and change views:
- title, ‘Add ’ or ‘Change ’ + your model class’
_meta.verbose_name - adminform is an instance of
AdminForm - is_popup, a boolean which is true when
_popupis passed as a request parameter - media is an instance of
django.forms.Media - inline_admin_formsets is a list of
InlineAdminFormSetobjects - errors is an instance of
AdminErrorList - root_path is the
root_pathattribute of theAdminSiteobject - app_label is your model class’
_meta.app_labelattribute
The way that Django renders a form in the admin view is to iterate over the adminform instance and then iterate over each FieldSet which in turn yield AdminField instances. All I want to do is layout the form fields, ignoring the fieldset groupings which may or may not be defined in the model’s ModelAdmin.fieldset attribute.
This turns out to be easy once you know how. The regular form is an attribute of the adminform object. So if your model has a field named “king_of_pop” you can refer to the form field in your template like so:
{{ adminform.form.king_of_pop.label_tag }}: {{ adminform.form.king_of_pop }}
Or if you want to save your finger tips you can use the with template tag:
{% with adminform.form as f %}
{{ f.king_of_pop.label_tag }}: {{ f.king_of_pop }}
{% endwith %}
Delving through the Django source while I tried to understand all of this I was struck by how Python defines hook functions for iteration and accessing attributes. Half of Python’s attraction is in how easy it is from the program author’s point of view to treat objects as built-in types like lists, dicts, etc.; the other half is the responsibility of the author of a Python module to encourage that same ease of use by implementing the related iteration protocols. It is harder to write a good Python module than it is to write a good Python program that uses a good module.