Gregor Müllegger
Computer Science Student
Google Summer of Code Student
Revised Form Rendering
Why?
Current form rendering:
{{ form.as_ul }}
Not very flexible ...
Why?
Because it is not possible to …
… change a widget on the fly
… change the order of form fields
… create a new user defined layout
… current layouts are hardcoded in the python source
Goals
Template based form rendering
layouts loaded from template structure
customize rendering in the template
Power to the Designers!
Backwards compatibility
Extensability
{% form %}
{% form %} will render and output a form instance
{{ myform }} will become {% form myform %}
{% form %}
Limit the fields to be rendered and their ordering:
{% form myform "firstname" "lastname" %}
{% form myform exclude "password" "username" %}
{% form %}
Define fields as hidden:
{% form myform hidden "honeypot" %}
{% form %}
You can use these options at once:
{% form myform
"firstname" "lastname" hidden "honeypot" %}
{% formlayout %}
Set layout with a modifier tag before the form is
rendered:
{% formlayout "ul" %}
{% form myform %}
Is the same as the current {{ myform.as_ul }}
{% formconfig %}
Form rendering modifiers must be used
inside a "scope":
{% formconfig %}
{% formlayout "ul" %}
{% form myform %}
{% endformconfig %}
{% formdefaults %}
You can specify default modifiers in your base
template:
{% formdefaults %}
{% formlayout "uniform" %}
{% endformdefaults %}
Helpers
{{ myform.field }} ->
{% formfield myform.field %}
{{ myform.field.label_tag }} ->
{% formlabel myform.field %}
{{ myform.field.help_text }} ->
{% formhelp myform.field %}
{{ myform.field.errors }} ->
{% formerrors myform.field %}
{{ myform.non_field_errors }} ->
{% formerrors myform.non_field_errors %}
Widgets
The GSoC project is based on Bruno Renié's
awesome work on template based widgets.
We want to take advantage of that
directly in the templates.
{% widget %}
Syntax:
{% widget <widget class|instance>
using <template name>
for <form field|field class|field name>
attrs <widget attributes>
with <additional template variables> %}
{% widget %}
Use a widget for a specific field:
{% widget widgets.PasswordInput
for myform.password %}
Change the template used to render a widget:
{% widget
using "check_username_availability.html"
for myform.username %}
{% widget %}
Use widget for all fields named "text":
{% widget widgets.Textarea for "text" %}
Use widget for all fields using a CharField:
{% widget widgets.Textarea
for formfields.CharField %}
{% widget %}
Inject template variable:
{% widget widgets.AutoComplete
for myform.country
with ajaxurl="/api/countries/" %}
Change widget attribute:
{% widget widgets.AutoComplete
for myform.country
attrs ajaxurl="/api/countries/" %}
Follow the project …
Look out on the django-developers mailing list
Follow me on twitter: @gregmuellegger
Watch the github repo:
https://github.com/gregmuellegger/django
(soc2011/form-rendering branch)
Feedback?
You will be using it …
… so complain now!
(it's appreciated)