Another option to consider in newer versions of Django is to use Reusable form templates to create a form template to call as {{ form.as_td }}, just like you would call {{ form.as_table }} in your template.
This has a few nice features:
- A
FormSet with each form wrapped in a <tr> but fields wrapped in <td> can coexist with other nice add-ons like django-dynamic-formset
- This method can be used for other elements your might want to render forms with
Steps:
- Create a
RenderMixin that implements as as_td() method, to be called as {{ form.as_td }} in your template
from django.forms.utils import RenderableMixin
class ColumnRenderableFormMixin(RenderableMixin):
def as_td(self):
"""Render as <td> elements excluding the surrounding <table> tag."""
return self.render(self.template_name_td)
- Create a reusable template in your app templates directory (or other suitable directory)
{% for field, errors in fields %}
<td>
{{ errors }}
{{ field }}
</td>
{% endfor %}
- Add the custom mixin to your form, and specify the
td.html template file path in the template_name_td class variable:
class SomeForm(ModelForm, ColumnRenderableFormMixin):
template_name_td = "someapp/td.html"
- In your view's template, render the form with
{{ form.as_td }}.
- If you're using a formset this would look like the following:
<table class="table">
{% for form in formset %}
<tr>
{{ form.as_td }}
</tr>
{% endfor %}
</table>