Form

Base class: Part

Describe a Form. Example:

class MyForm(Form):
    a = Field()
    b = Field.email()

form = MyForm().bind(request=request)

You can also create an instance of a form with this syntax if it’s more convenient:

form = Form(
    fields=dict(
        a=Field(),
        b=Field.email(),
    ),
).bind(request=request)

In the common case the fields namespace will contain only instances of Field, but iommi actually supports arbitrary Part objects. For example:

form = Form(
    fields=dict(
        # Display a and b inside a box
        box=html.div(
            attrs__class__box=True,
            children__a=Field(),
            children__b=Field.email(),
        ),
        # And c regularly
        c=Field(),
    )
)

So that writing the application logic (e.g. validation and post handlers) is independent of minor changes to the layout, after bind the fields namespace of the form will contain only instances of Field keyed by their _name independently of how deep they are in the hierarchy. Given the above, an appropriate post_handler would be:

def post_handler(form, **_):
    if not form.is_valid():
        return

    print(form.fields.a.value, form.fields.b.value, form.fields.c.value)
    # And not:
    # print(form.fields.box.a.value, form.fields.box.b.value, form.fields.c.value)

Refinable members

action_class

Type: Type[iommi.action.Action]

actions

Type: Namespace

actions_template     (evaluated)

Type: Union[str, iommi._web_compat.Template]

Default: iommi/form/actions.html

after     (evaluated)

Type: Union[int, str]

See after

assets

Type: Namespace

See assets

attr     (evaluated)

Type: str

See attr

attrs     (evaluated)

Type: Attrs

Cookbook:

How do I make a freetext search field?

auto

Type: FormAutoConfig

See auto

Cookbook:

How do I enable a reverse foreign key relationship?

How do I say which fields to include when creating a form from a model?

editable

Type: bool

Default: True

Cookbook:

How do I make a field non-editable?

endpoints

Type: Namespace

errors

Type: Errors

extra

Type: Dict[str, Any]

See extra

Cookbook:

How do I change where the form redirects to after completion?

extra_evaluated

Type: Dict[str, Any]

See extra

extra_params

field_group

Type: Namespace

fields

Type: Namespace

Cookbook:

How do I make a fields choices depend on another field?

How do I nest multiple forms?

fields_template     (evaluated)

Type: Union[str, iommi._web_compat.Template]

Cookbook:

How do I use templates for fields?

h_tag     (evaluated)

Type: Union[iommi.fragment.Fragment, str]

See title

include     (evaluated)

Type: bool

See include

instance

Type: Any

iommi_style

Type: str

member_class

Type: Type[iommi.form.Field]

model     (evaluated)

Type: Type[django.db.models.base.Model]

page_class

Type: Type[iommi.page.Page]

post_validation

read_nested_form_from_instance

Read the nested forms instance from the parent forms instance.

This is analogous to Field.read_from_instance but for nested forms.

template     (evaluated)

Type: Union[str, iommi._web_compat.Template]

Default: iommi/form/form.html

See template

title     (evaluated)

Type: Fragment

See title

write_nested_form_to_instance

Write the nested_form to the instance.

This is analogous to Field.write_to_instance but for nested forms.

Shortcuts

Form.create

Parent: Form.crud

Defaults

  • actions__submit__post_handler
    • iommi.form.create_object__post_handler

  • extra__is_create
    • True

Form.create_or_edit

Parent: Form.crud

Defaults

  • actions__submit__post_handler
    • iommi.form.create_or_edit_object__post_handler

  • extra__is_create
    • None

Cookbook:

How do I make a create or edit form?

Form.crud

Defaults

  • extra__pre_save_all_but_related_fields
    • lambda **kwargs: None, # pragma: no mutate

  • extra__on_save_all_but_related_fields
    • lambda **kwargs: None, # pragma: no mutate

  • extra__pre_save
    • lambda **kwargs: None, # pragma: no mutate

  • extra__on_save
    • lambda **kwargs: None, # pragma: no mutate

  • extra__on_delete
    • lambda **kwargs: None, # pragma: no mutate

  • extra__redirect
    • lambda redirect_to, **_: HttpResponseRedirect(redirect_to)

  • extra__redirect_to
    • None

  • extra__crud_type
    • lambda form, **_: 'create' if form.instance is None else 'edit'

  • extra__new_instance
    • lambda form, **_: form.model()

  • auto
    • Namespace()

Form.delete

Parent: Form.crud

Defaults

  • actions__submit__call_target__attribute
    • delete

  • actions__submit__post_handler
    • iommi.form.delete_object__post_handler

  • extra__crud_type
    • delete

  • editable
    • False

  • fields__iommi_default_text
    • {'call_target': <class 'iommi.fragment.Fragment'>, 'include': <function Form.<lambda> at 0x726dcb9460c0>, 'after': 0, 'tag': 'p', 'children__text': <function Form.<lambda> at 0x726dcb946660>}

Form.edit

Parent: Form.crud

Defaults

  • actions__submit__post_handler
    • iommi.form.edit_object__post_handler

  • extra__is_create
    • False

Methods

add_error

Explicitly add an error message to the forms global error set.

Example:

def post_validation(form, **_):
    form.add_error('global error')

form = Form.create(
    auto__model=Album,
    post_validation=post_validation,
)
▼ Hide result

apply

Write the new values specified in the form into the instance specified.

as_view

get_errors

Get a dict containing two keys:

  • global for errors global to the entire form.

  • fields for errors specific to fields. This is itself a dict with a key for each field.

is_target

is_valid

Is the form valid? Can be called inside forms post_validation hook to determine if the individual fields were all valid.

on_bind

on_refine_done

own_evaluate_parameters

validate

Static methods

apply_field

Class methods

fields_from_model