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][django11].
Django uses an instance of `ModelAdmin` (defined in [`django.contrib.admin.options`][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 `_popup` is passed as a request parameter
– **media** is an instance of [`django.forms.Media`][media]
– **inline_admin_formsets** is a list of [`InlineAdminFormSet`][inlineset] objects
– **errors** is an instance of [`AdminErrorList`][errors]
– **root_path** is the `root_path` attribute of the `AdminSite` object
– **app_label** is your model class’ `_meta.app_label` attribute
The way that Django renders a form in the admin view is to iterate over the `adminform` instance and then iterate over each [`FieldSet`][fieldset] which in turn yield [`AdminField`][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]:
{% 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][hooks]. 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.
[django11]: http://code.djangoproject.com/browser/django/tags/releases/1.1
[options]: http://code.djangoproject.com/browser/django/tags/releases/1.1/django/contrib/admin/options.py#L175
[fieldset]: http://code.djangoproject.com/browser/django/tags/releases/1.1/django/contrib/admin/helpers.py#L50
[adminfield]: http://code.djangoproject.com/browser/django/tags/releases/1.1/django/contrib/admin/helpers.py#L82
[with]: http://docs.djangoproject.com/en/dev/ref/templates/builtins/#with
[media]: http://docs.djangoproject.com/en/dev/topics/forms/media/
[inlineset]: http://code.djangoproject.com/browser/django/tags/releases/1.1/django/contrib/admin/helpers.py#L102
[errors]: http://code.djangoproject.com/browser/django/tags/releases/1.1/django/contrib/admin/helpers.py#L198
[hooks]: http://docs.python.org/reference/datamodel.html#emulating-container-types
Hi David–
Thanks for writing this. I was struggling w/ how to access the fields for a custom admin form I was trying to write. This is just what I needed. Thanks!