Privacy Policy
Snippets index

  Form rendering with Django 4.1

...

"as_*" methods to allow for customisation of the form layout:

  • as_table (the default)
  • as_ul
  • as_p
  • as_div (new in 4.1)

Sample form rendering by looping over each field in the form:

{% for field in form %}
<div class="mb-3">
    {% if field.use_fieldset %}
        <fieldset>
        {% if field.label %}{{ field.legend_tag }}{% endif %}
    {% else %}
        {% if field.label %}{{ field.label_tag }}{% endif %}
    {% endif %}
        <p class="text-muted">{{ form.day.help_text }}</p>
        {{ field.errors }}
        {{ field }}
    {% if field.use_fieldset %}
        </fieldset>
    {% endif %}
</div>
{% endfor %}

Tip: you can use field_order on the form to customize the order the fields

However, we'd just lie to write:

{{ form }}

Set template_name on your class. Ensure the template loader can find the template.

class ContactForm(forms.Form):
    template_name = "form_template.html"

or call render() on your form in a view and providing a template_name to customize the template per instance:

def my_view(request):
    form = ContactForm()
    context = {
        'form': form.render(template_name="form_template.html"),
    }

You can also use FORM_RENDER setting to use the template site wide:

from django.forms.renderers import TemplateSetting

class CustomFormRenderer(TemplateSetting):
    form_template_name = "form_template.html"

    # also works for formset tool
    formset_template_name = ...


FORM_RENDERER = "main.forms.CustomFormRenderer"

Finally:

  • Templates are also available for:
    • Labels via template_name_label on your Form
    • Errors via a custom error_class on your Form