Field ===== Base class: :doc:`Part` Class that describes a field, i.e. what input controls to render, the label, etc. See :doc:`Form` for more complete examples. The life cycle of the data is: 1. `raw_data`: will be set if the corresponding key is present in the HTTP request 2. `parsed_data`: set if parsing is successful, which only happens if the previous step succeeded 3. `value`: set if validation is successful, which only happens if the previous step succeeded Note that, in addition to the parameters with the defined behavior below, you can pass in any keyword argument you need yourself, including callables that conform to the protocol, and they will be added and evaluated as members. All these parameters can be callables, and if they are, will be evaluated with the keyword arguments form and field. The only exceptions are `is_valid` (which gets `form`, `field` and `parsed_data`), `render_value` (which takes `form`, `field` and `value`) and `parse` (which gets `form`, `field`, `string_value`). Example of using a lambda to specify a value: .. code-block:: python Field(attrs__id=lambda form, field: 'my_id_%s' % field._name) Refinable members ----------------- * `after`     (:ref:`evaluated `) Set the order of columns, see the `howto `_ for an example. Type: `Union[int, str]` * `assets` Type: `Namespace` * `attr`     (:ref:`evaluated `) The attribute path to apply or get the data from. For example using `foo__bar__baz` will result in `your_instance.foo.bar.baz` will be set by the `apply()` function. Defaults to same as name Type: `str` * `attrs`     (:ref:`evaluated `) A dict containing any custom html attributes to be sent to the `input__template`. Type: :doc:`Attrs` * `choice_display_name_formatter` Callback given the keyword argument `choice` in addition to standard parameters, to obtain the display name representing a given choice to the end user. Default implementation will use `str(choice)` Type: `Callable[..., str]` Default: `lambda choice, **_: '%s' % choice` * `choice_id_formatter` Callback given the keyword argument `choice` in addition to standard parameters, to obtain the string value to represent the identity of a given `choice`. Default implementation will use `str(choice)` Type: `Callable[..., str]` Default: `lambda choice, **_: '%s' % choice` * `choice_to_optgroup` Type: `Optional[Callable[..., Optional[str]]]` * `choices`     (:ref:`evaluated `) Type: `Callable[..., List[Any]]` * `display_name`     (:ref:`evaluated `) The text in the HTML label tag. Default: `capitalize(name).replace('_', ' ')` Type: `str` * `editable`     (:ref:`evaluated `) Is this field editable. Type: `bool` Default: `True` * `empty_label`     (:ref:`evaluated `) Type: `str` Default: `---` * `endpoints` Type: `Namespace` * `errors` Type: `Errors` * `extra` Type: `Dict[str, Any]` * `extra_evaluated` Type: `Dict[str, Any]` * `extra_params` * `group`     (:ref:`evaluated `) Type: `str` * `help` Type: :doc:`Fragment` * `help_text` The help text will be grabbed from the django model if specified and available. * `include`     (:ref:`evaluated `) Type: `bool` * `initial`     (:ref:`evaluated `) Initial value of the field Type: `Any` * `input` Type: :doc:`Fragment` * `iommi_style` Type: `str` * `is_boolean`     (:ref:`evaluated `) Type: `bool` Default: `False` * `is_list`     (:ref:`evaluated `) Interpret request data as a list (can NOT be a callable). Default: `False`` Type: `bool` Default: `False` * `is_valid` Validation function. Should return a tuple of `(bool, reason_for_failure_if_bool_is_false)` or raise ValidationError. .. code-block:: python form = Form.create( auto__model=Artist, fields__name__is_valid=lambda parsed_data, **_: (parsed_data.startswith('H'), 'Must start with H!'), ) .. raw:: html
▼ Hide result
* `label` Type: :doc:`Fragment` * `model`     (:ref:`evaluated `) Type: `Optional[Type[django.db.models.base.Model]]` * `model_field` Type: `Optional[django.db.models.fields.Field]` * `model_field_name` * `non_editable_input` Type: :doc:`Fragment` Default: `{'call_target': , 'children__text': at 0x7f735cb8a840>, 'attrs__value': at 0x7f735cb8a8e0>, 'attrs__disabled': at 0x7f735cb8a980>}` * `parse` Parse function. Default just returns the string input unchanged. This function can raise `ValueError` or `ValidationError` to produce a field error message. * `parse_empty_string_as_none`     (:ref:`evaluated `) Type: `bool` Default: `True` * `parsed_data`     (:ref:`evaluated `) Type: `Any` * `post_validation` * `raw_data` Type: `str` * `read_from_instance` Callback to retrieve value from edited instance. Invoked with parameters field and instance. * `render_value` Render the parsed and validated value into a string. Default just converts to `str`. .. code-block:: python sentinel = '!!custom!!' form = Form( fields__foo=Field( initial='not sentinel value', render_value=lambda form, field, value, **_: sentinel, ) ) .. raw:: html
▼ Hide result
* `required`     (:ref:`evaluated `) If the field is a required field. Default: `True` Type: `bool` Default: `True` * `search_fields` * `strip_input`     (:ref:`evaluated `) Runs the input data through standard python .strip() before passing it to the parse function (can NOT be callable). Default: `True` Type: `bool` Default: `True` * `tag`     (:ref:`evaluated `) Type: `str` Default: `div` * `template`     (:ref:`evaluated `) Django template filename or `Template` instance for the entire row. Normally you shouldn't need to override on this level. Prefer overriding `input__template`, `label__template` or `error__template` as needed. Type: `Union[str, iommi._web_compat.Template]` * `write_to_instance` Callback to write value to instance. Invoked with parameters field, instance and value. Shortcuts --------- `Field.boolean` ^^^^^^^^^^^^^^^ Defaults ++++++++ * `parse` * `iommi.form.bool_parse` * `required` * `False` * `is_boolean` * `True` `Field.boolean_tristate` ^^^^^^^^^^^^^^^^^^^^^^^^ Parent: Field.choice_ Defaults ++++++++ * `choices` * `[True, False]` * `choice_id_formatter` * `lambda choice, **_: 'true' if choice else 'false'` * `choice_display_name_formatter` * `lambda choice, **_: gettext('Yes') if choice else gettext('No')` * `parse` * `iommi.form.boolean_tristate__parse` * `required` * `False` `Field.checkboxes` ^^^^^^^^^^^^^^^^^^ Parent: Field.multi_choice_ Defaults ++++++++ * `input__attrs__id` * `None` * `extra_evaluated__id` * `iommi.form.default_input_id` `Field.choice` ^^^^^^^^^^^^^^ Shortcut for single choice field. If required is false it will automatically add an option first with the value '' and the title '---'. To override that text pass in the parameter empty_label. Defaults ++++++++ * `required` * `True` * `is_list` * `False` * `is_valid` * `iommi.form.choice_is_valid` * `input__attrs__multiple` * `lambda field, **_: True if field.is_list else None` * `parse` * `iommi.form.choice_parse` `Field.choice_queryset` ^^^^^^^^^^^^^^^^^^^^^^^ Defaults ++++++++ * `parse` * `iommi.form.choice_queryset__parse` * `choice_id_formatter` * `lambda choice, **_: choice.pk` * `endpoints__choices__func` * `iommi.form.choice_queryset__endpoint_handler` * `is_valid` * `iommi.form.choice_queryset__is_valid` * `extra__filter_and_sort` * `iommi.form.choice_queryset__extra__filter_and_sort` * `extra__model_from_choices` * `iommi.form.choice_queryset__extra__model_from_choices` `Field.date` ^^^^^^^^^^^^ Defaults ++++++++ * `parse` * `iommi.form.date_parse` * `render_value` * `iommi.form.date_render_value` `Field.datetime` ^^^^^^^^^^^^^^^^ Defaults ++++++++ * `parse` * `iommi.form.datetime_parse` * `render_value` * `iommi.form.datetime_render_value` * `extra_evaluated__is_tz_aware` * `lambda **_: settings.USE_TZ` `Field.decimal` ^^^^^^^^^^^^^^^ Parent: Field.number_ Defaults ++++++++ * `parse` * `iommi.form.decimal_parse` `Field.duration` ^^^^^^^^^^^^^^^^ Parent: Field.text_ Defaults ++++++++ * `parse` * `iommi.form.duration_parse` * `render_value` * `iommi.form.duration_render_value` `Field.email` ^^^^^^^^^^^^^ Defaults ++++++++ * `input__attrs__type` * `email` * `parse` * `iommi.form.email_parse` `Field.file` ^^^^^^^^^^^^ Defaults ++++++++ * `input__attrs__type` * `file` * `raw_data` * `iommi.form.file__raw_data` * `write_to_instance` * `iommi.form.file_write_to_instance` * `extra__django_related_field` * `True` `Field.float` ^^^^^^^^^^^^^ Parent: Field.number_ Defaults ++++++++ * `parse` * `iommi.form.float_parse` `Field.foreign_key` ^^^^^^^^^^^^^^^^^^^ `Field.foreign_key_reverse` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Defaults ++++++++ * `editable` * `False` * `display_name` * `lambda field, **_: capitalize(field.model_field.related_model._meta.verbose_name_plural)` * `help_text` * `None` `Field.hardcoded` ^^^^^^^^^^^^^^^^^ Defaults ++++++++ * `template` * `iommi/blank.html` `Field.heading` ^^^^^^^^^^^^^^^ Defaults ++++++++ * `editable` * `False` * `attr` * `None` `Field.hidden` ^^^^^^^^^^^^^^ Defaults ++++++++ * `input__attrs__type` * `hidden` * `attrs__style__display` * `none` `Field.image` ^^^^^^^^^^^^^ Parent: Field.file_ Defaults ++++++++ * `template` * `iommi/form/image_row.html` `Field.info` ^^^^^^^^^^^^ Shortcut to create an info entry. Defaults ++++++++ * `editable` * `False` * `attr` * `None` `Field.integer` ^^^^^^^^^^^^^^^ Parent: Field.number_ Defaults ++++++++ * `parse` * `iommi.form.int_parse` `Field.many_to_many` ^^^^^^^^^^^^^^^^^^^^ `Field.many_to_many_reverse` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Defaults ++++++++ * `display_name` * `lambda field, **_: capitalize(field.model_field.remote_field.model._meta.verbose_name_plural)` * `help_text` * `None` `Field.multi_choice` ^^^^^^^^^^^^^^^^^^^^ Parent: Field.choice_ Defaults ++++++++ * `is_list` * `True` `Field.multi_choice_queryset` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Defaults ++++++++ * `is_list` * `True` `Field.non_rendered` ^^^^^^^^^^^^^^^^^^^^ Defaults ++++++++ * `template` * `` * `editable` * `False` `Field.number` ^^^^^^^^^^^^^^ `Field.password` ^^^^^^^^^^^^^^^^ Defaults ++++++++ * `input__attrs__type` * `password` `Field.phone_number` ^^^^^^^^^^^^^^^^^^^^ Defaults ++++++++ * `is_valid` * `iommi.form.phone_number_is_valid` `Field.radio` ^^^^^^^^^^^^^ Parent: Field.choice_ Defaults ++++++++ * `input__attrs__id` * `None` * `extra_evaluated__id` * `iommi.form.default_input_id` `Field.text` ^^^^^^^^^^^^ Defaults ++++++++ * `input__attrs__type` * `text` `Field.textarea` ^^^^^^^^^^^^^^^^ Defaults ++++++++ * `input__tag` * `textarea` * `input__attrs__type` * `None` * `input__attrs__value` * `None` * `input__attrs__readonly` * `lambda field, **_: True if field.editable is False else None` * `input__children__text` * `lambda field, **_: field.rendered_value` `Field.time` ^^^^^^^^^^^^ Defaults ++++++++ * `parse` * `iommi.form.time_parse` * `render_value` * `iommi.form.time_render_value` `Field.url` ^^^^^^^^^^^ Defaults ++++++++ * `input__attrs__type` * `url` * `parse` * `iommi.form.url_parse` Methods ------- `add_error` ^^^^^^^^^^^ `bind_from_instance` ^^^^^^^^^^^^^^^^^^^^ `get_errors` ^^^^^^^^^^^^ `on_bind` ^^^^^^^^^ `on_refine_done` ^^^^^^^^^^^^^^^^ `own_evaluate_parameters` ^^^^^^^^^^^^^^^^^^^^^^^^^ Class methods ------------- `from_model` ^^^^^^^^^^^^