We love Django here at Isotoma, and we love using Django’s awesome form classes to generate self-generating, self-validating, [X]HTML forms.

However, in practically every new Django project I find myself doing the same thing over and over again (and I know others do too): breaking the display of a Django form instance up into individual fields, with appropriate mark-up wrappers.

Effectively I keep recreating the output of BaseForm.as_p/as_ul/as_table with template tags and mark-up.

For example, outputting a login form, rather than doing:

{{ form.as_p }}

We would do:

<p> {% if form.username.errors %} {% for error in form.username.errors %} {{ error }} {% endfor %} {% endif %} {{ form.username.label }} {{ form.username }} </p> <p> {% if form.password.errors %} {% for error in form.password.errors %} {{ error }} {% endfor %} {% endif %} {{ form.password.label }} {{ form.password }} </p>

Why would you want to do this? There are several reasons, but generally it’s to apply custom mark-up to a particular element (notice I said mark-up, not styling, that can be done with the generated field IDs), as well as completely customising the output of the form (using <div> ‘s instead etc.), and also because some designers tend to prefer this way of looking at a template.

“But”, you might say, “Django already creates all this for us with the handy as_p/as_ul/as_table methods, can you just take the ouput from that?”

Well, yes, in fact on a project a couple of weeks ago that’s exactly what I did, outputting as_p in a template, and then editing the source chucked out in a browser.

Which gave me the idea to create a simple little tool to do this for me, but with the Django template tags for dynamically outputting the field labels and fields themselves.

I created django-form-scaffold to do just this, and now I can do this from a Python shell:

>>> from dfs import scaffold >>> from MyProject.MyApp.forms import MyForm >>> form = MyForm() >>> # We can pass either an instance of our form class >>> # or the class itself, but better to pass an instance. >>> print scaffold.as_p(form) {% if form.email.errors %}{% for error in form.email.errors %} {{ error }}{% endfor %}{% endif %} <p>{{ form.email.label }} {{ form.email }}</p> {% if form.password1.errors %}{% for error in form.password1.errors %} {{ error }}{% endfor %}{% endif %} <p>l{{ form.password1.label }} {{ form.password1 }}</p> {% if form.password2.errors %}{% for error in form.password2.errors %} {{ error }}{% endfor %}{% endif %} <p>{{ form.password2.label }} {{ form.password2 }}</p>

Copy and paste this into a template, tweak, and Robert’s your mother’s brother.