Good form: How Django’s form rendering improved during the 4.x series
05-31, 11:35–12:05 (Europe/London), Music Hall

If you render forms server side then this talk is for you! How to make best use of Django’s form rendering features introduced during the 4.x series to help you simplify your form logic.


Historically Django has used concatenation of strings to render its forms with various as_* methods to render forms in different styles. While great to get a project up and running many folk will have used a third party library to help ease customisation of forms.

During the 4.x series a number of changes have been made including a switch to use the template engine to render forms, the ways in which the template can be set has grown and a new default style will replace as_table from Django 5.0.

We’ll cover:

⁃ What is a form, a field and a widget? What common attributes can I set to avoid logic in my template?

⁃ The switch to template based rendering, and that a template can now be used to render your form. We’ll work through a concrete example how this can be used simplify logic in your templates.

⁃ How the rendering of your form can be set on a per-project, per-form and per-instance basis.

⁃ Introduction of a new as_div template style, and why the other styles are no longer recommended.

⁃ Future ideas on how Django can ease form rendering further.

⁃ So with all this change, do I still need 3rd-party package such as crispy-forms?

May your form be good!

David's an accountant by profession and has been contributing to Django since 2019.

Since that first commit to improve crispy-forms' Bootstrap4 templates, David has become maintainer of the popular django-crispy-forms package. In addition with 100+ commits to django/django he is also now a member of Django's Triage and Review team.

Major feature contributions to Django itself over the Django 4.x cycle include the switch to template based form rendering and improvements in form rendering accessibility which led to introduction of a new form template which will become the default from Django 5.0.