How do I supply a custom parser for a field?#
Pass a callable to the
parse member of the field:
form = Form( auto__model=Track, fields__index__parse= lambda field, string_value, **_: int(string_value[:-3]), )
How do I make a field non-editable?#
Pass a callable or
bool to the
editable member of the field:
form = Form( auto__model=Album, fields__name__editable= lambda request, **_: request.user.is_staff, fields__artist__editable=False, )
How do I make an entire form non-editable?#
This is a very common case so there’s a special syntax for this: pass a
bool to the form:
form = Form.edit( auto__instance=album, editable=False, )
How do I supply a custom validator?#
Pass a callable that has the arguments
parsed_data. Return a tuple
(is_valid, 'error message if not valid').
form = Form.create( auto__model=Album, auto__include=['name'], fields__name__is_valid= lambda form, field, parsed_data: (parsed_data == 'only this value is valid', 'invalid!'), )
How do I validate multiple fields together?#
post_validation hook on the
form. It is run after all the individual fields validation
has run. But note that it is run even if the individual fields validation was not successful.
How do I exclude a field?#
How do I say which fields to include when creating a form from a model?#
Form() has four methods to select which fields are included in the final form:
auto__includeparameter: this is a list of strings for members of the model to use to generate the form.
auto__excludeparameter: the inverse of
include. If you use this the form gets all the fields from the model excluding the ones with names you supply in
for more advanced usages you can also pass the
includeparameter to a specific field like
fields__my_field__include=True. Here you can supply either a
boolor a callable like
fields__my_field__include=lambda request, **_: request.user.is_staff.
you can also add fields that are not present in the model by passing configuration like
fields__foo__attr='bar__baz'(this means create a
foothat reads its data from
bar.baz). You can either pass configuration data like that, or pass an entire
How do I supply a custom initial value?#
Pass a value or callable to the
form = Form( auto__model=Album, fields__name__initial='Paranoid', fields__year__initial=lambda field, form, **_: 1970, )
If there are
GET parameters in the request, iommi will use them to fill in the appropriate fields. This is very handy for supplying links with partially filled in forms from just a link on another part of the site.
How do I set if a field is required?#
Normally this will be handled automatically by looking at the model definition, but sometimes you want a form to be more strict than the model. Pass a
bool or a callable to the
form = Form( auto__model=Album, fields__name__required=True, fields__year__required=lambda field, form, **_: True, )
How do I change the order of the fields?#
You can change the order in your model definitions as this is what iommi uses. If that’s not practical you can use the
after member. It’s either the name of a field or an index. There is a special value
LAST to put a field last.
from iommi import LAST form = Form( auto__model=Album, fields__name__after=LAST, fields__year__after='artist', fields__artist__after=0, )
This will make the field order
If there are multiple fields with the same index or name the order of the fields will be used to disambiguate.
How do I specify which model fields the search of a choice_queryset use?#
Form.choice_queryset uses the registered search fields for filtering and ordering.
See Registrations for how to register one. If present it will default
to a model field
In special cases you can override which attributes it uses for
searching by specifying
form = Form( auto__model=Album, fields__name__search_fields=('name', 'year'), )
This last method is discouraged though, because it will mean searching behaves differently in different parts of your application for the same data.
How do I insert a CSS class or HTML attribute?#
How do I override rendering of an entire field?#
Pass a template name:
form = Form( auto__model=Album, fields__year__template='my_template.html', )
form = Form( auto__model=Album, fields__year__template=Template('This is from the inline template'), )
How do I override rendering of the input field?#
Pass a template name or a
Template object to the
form = Form( auto__model=Album, fields__year__input__template='my_template.html', )
form = Form( auto__model=Album, fields__year__input__template=Template('This is from the inline template'), )
How do I change how fields are rendered everywhere in my project?#
Define a custom style and override the appropriate fields. For
example here is how you could change
Field.date to use a text
based input control (as opposed to the date picker that
my_style = Style(bootstrap, Field__shortcuts__date__input__attrs__type='text')
When you do that you will get English language relative date parsing (e.g. “yesterday”, “3 days ago”) for free, because iommi used to use a text based input control and the parser is applied no matter what (its just that when using the default date picker control it will always only see ISO-8601 dates).
How do I change where the form redirects to after completion?#
iommi by default redirects to
.. after edit/create/delete. You can
override this via two methods:
extra__redirect_to: a string with the url to redirect to. Relative URLs also work.
extra__redirect: a callable that gets at least the keyword arguments
Form that after create redirects to the edit page of the object:
form = Form.create( auto__model=Album, extra__redirect= lambda form, **_: HttpResponseRedirect( form.instance.get_absolute_url() + 'edit/' ), )
Form that after edit stays on the edit page:
form = Form.edit( auto__instance=album, extra__redirect_to='.', )
How do I make a fields choices depend on another field?#
The contents of the form is sent with any AJAX requests, so we can access the value of the other fields to do the filtering:
def album_choices(form, **_): if form.fields.artist.value: return Album.objects.filter(artist=form.fields.artist.value) else: return Album.objects.all() Form( auto__model=Track, fields__artist=Field.choice_queryset( attr=None, choices=Artist.objects.all(), after=0, ), fields__album__choices=album_choices, )