form.core

Module Contents

Classes

DependencyDict

dict() -> new empty dictionary

Form

Extends wtforms.Form with useful methods and integrations needed in

Fieldset

Defines a fieldset with a list of fields.

FieldDependency

Defines a dependency to a field. The given field(s) must have the given

Pricing

Defines pricing on a field, returning the correct price for the field

Functions

merge_forms(→ type[_FormT])

Takes a list of forms and merges them.

enforce_order(→ type[_FormT])

Takes a list of fields used in a form_class and enforces the

move_fields(→ type[_FormT])

Reorders the given fields (given by name) by inserting them directly

Attributes

_FormT

class form.core.DependencyDict[source]

Bases: typing_extensions.TypedDict

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)

field_id: str[source]
raw_choice: object[source]
invert: bool[source]
choice: object[source]
form.core._FormT[source]
class form.core.Form(formdata: MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, extra_filters: Mapping[str, Sequence[Any]] | None = None, **kwargs: Any)[source]

Bases: wtforms.Form

Extends wtforms.Form with useful methods and integrations needed in OneGov applications.

Fieldsets

This form supports fieldsets (which WTForms doesn’t recognize). To put fields into a fieldset, add a fieldset attribute to the field during class definition:

class MyForm(Form):
    first_name = StringField('First Name', fieldset='Name')
    last_name = StringField('Last Name', fieldset='Name')
    comment = StringField('Comment')

A form created like this will have two fieldsets, one visible fieldset with the legend set to ‘Name’ and one invisible fieldset containing ‘comment’.

Fieldsets with the same name are not automatically grouped together. Instead, fields are taken in the order they are defined and put into the same fieldset, if the previous fieldset has the same name.

That is to say, in this example, we get three fieldsets:

class MyForm(Form):
    a = StringField('A', fieldset='1')
    b = StringField('B', fieldset='2')
    c = StringField('C', fieldset='1')

The first fieldset has the label ‘1’ and it contains ‘a’. The second fieldset has the label ‘2’ and it contains ‘b’. The third fieldset has the label ‘3’ and it contains ‘c’.

This ensures that all fields are in either a visible or an invisible fieldset (see Fieldset.is_visible()).

Dependencies

This form also supports dependencies. So field b may depend on field a, if field a has a certain value, field b is shown on the form (with some javascript) and its validators are actually executed. If field a does not have the required value, field b is hidden with javascript and its validators are not executed.

The validators which are skipped are only the validators passed with the field, the validators on the field itself are still invoked (we can’t skip them). However, only if the optional field is not empty. That is we prevent invalid values no matter what, but we allow for empty values if the dependent field does not have the required value.

This sounds a lot more complicated than it is:

class MyForm(Form):

    option = RadioField('Option', choices=[
        ('yes', 'Yes'),
        ('no', 'No'),
    ])
    only_if_no = StringField(
        label='Only Shown When No',
        validators=[InputRequired()],
        depends_on=('option', 'no')
    )

Pricing

Pricing is a way to attach prices to certain form fields. A total price is calcualted depending on the selections the user makes:

class MyForm(Form):

    ticket_insurance = RadioField('Option', choices=[
        ('yes', 'Yes'),
        ('no', 'No')
    ], pricing={
        'yes': (10.0, 'CHF')
    })

    stamps = IntegerRangeField(
    'No. Stamps',
    range=range(0, 30),
    pricing={range(0, 30): (0.85, 'CHF')}
)

    delivery = RadioField('Delivery', choices=[
        ('pick_up', 'Pick up'),
        ('post', 'Post')
    ], pricing={
        'post': (5.0, 'CHF', True)
    })

    discount_code = StringField('Discount Code', pricing={
        'CAMPAIGN2017': (-5.0, 'CHF')
    })

Note that the pricing has no implicit meaning. This is simply a way to attach prices and to get the total through the prices() and total() calls. What you do with these prices is up to you.

Pricing can optionally take a third boolean value indicating that this option will make credit card payments mandatory.

property has_required_email_field: bool[source]

Returns True if the form has a required e-mail field.

property title_fields: list[str][source]

Fields used to generate a title.

property ensurances: Iterator[Callable[[], bool]][source]

Returns the ensurances that need to be checked when validating.

This property may be overridden if only a subset of all ensurances should actually be enforced.

fieldsets: list[Fieldset][source]
hidden_fields: set[str][source]
classmethod clone() type[typing_extensions.Self][source]

Creates an independent copy of the form class.

The fields of the so called class may be manipulated without affecting the original class.

process_fieldset() Iterator[None][source]

Processes the fieldset parameter on the fields, which puts fields into fieldsets.

In the process the fields are altered so that wtforms recognizes them again (that is, attributes only known to us are removed).

See Form for more information.

process_depends_on() Iterator[None][source]

Processes the depends_on parameter on the fields, which adds the ability to have fields depend on values of other fields.

Supported are dependencies to boolean fields and choices. Search the source code for depends_on for plenty of examples.

For checkboxes, note that the value is ‘y’ (string) or ‘!y’ for the inverse.

In the process the fields are altered so that wtforms recognizes them again (that is, attributes only known to us are removed).

See Form for more information.

process_pricing() Iterator[None][source]

Processes the pricing parameter on the fields, which adds the ability to have fields associated with a price.

See Form for more information.

render_display(field: wtforms.Field) Markup | None[source]

Renders the given field for display (no input). May be overwritten by descendants to return different html, or to return None.

If None is returned, the field is not rendered.

is_visible_through_dependencies(field_id: str) bool[source]

Returns true if the given field id has visible because all of it’s parents are visible. A field is invisible if its dependency is not met.

is_hidden(field: wtforms.Field) bool[source]

True if the given field should be hidden. The effect of this is left to the application (it might not render the field, or add a class which hides the field).

hide(field: wtforms.Field) None[source]

Marks the given field as hidden.

show(field: wtforms.Field) None[source]

Marks the given field as visibile.

prices() list[tuple[str, onegov.pay.Price]][source]

Returns the prices of all selected items depending on the formdata.

total() onegov.pay.Price | None[source]

Returns the total amount of all prices.

submitted(request: onegov.core.request.CoreRequest) bool[source]

Returns true if the given request is a successful post request.

ignore_csrf_error() None[source]

Removes the csrf error from the form if found, after validation.

Use this only if you know what you are doing (really, never).

match_fields(include_classes: Iterable[type[Field]] | None = None, exclude_classes: Iterable[type[Field]] | None = None, required: bool | None = None, limit: int | None = None) list[str][source]

Returns field ids matching the given search criteria.

Include_classes:

A list of field classes which should be included.

Excluded_classes:

A list of field classes which should be excluded.

Required:

True if required fields only, False if no required fields.

Limit:

If > 0, limits the number of returned elements.

All parameters may be set to None disable matching it to anything.

is_required(field_id: str) bool[source]

Returns true if the given field_id is required.

get_useful_data(exclude: Collection[str] | None = None) dict[str, Any][source]

Returns the form data in a dictionary, by default excluding data that should not be stored in the db backend.

populate_obj(obj: object, exclude: Collection[str] | None = None, include: Collection[str] | None = None) None[source]

A reimplementation of wtforms populate_obj function with the addage of optional include/exclude filters.

If neither exclude nor include is passed, the function works like it does in wtforms. Otherwise fields are considered which are included but not excluded.

process(formdata: _MultiDictLike | None = None, obj: object | None = None, data: Mapping[str, Any] | None = None, extra_filters: Mapping[str, Sequence[Any]] | None = None, **kwargs: Any) None[source]

Calls process_obj() if process() was called with the obj keyword argument.

This saves an extra check in many cases where we want to extend the process function, but only if an obj has been provided.

process_obj(obj: object) None[source]

Called by process() if an object was passed.

Do not use this function directly. To process an object, you should call form.process(obj=obj) instead.

delete_field(fieldname: str) None[source]

Removes the given field from the form and all the fieldsets.

validate(extra_validators: Mapping[str, Sequence[Any]] | None = None) bool[source]

Adds support for ‘ensurances’ to the form. An ensurance is a method which is called during validation when all the fields have been populated. Therefore it is a good place to validate against multiple fields.

All methods which start with ensure_ are ensurances. If and only if an ensurance returns False it is considered to have failed. In this case the validate method returns False as well. If None or ‘’ or any other falsy value is returned, no error is assumed! This avoids having to return an extra True at the end of each ensurance.

When one ensurance fails, the others are still run. Also, there’s no error display mechanism. Showing an error is left to the ensurance itself. It can do so by adding messages to the various error lists of the form or by showing an alert through the request.

static as_maybe_markdown(raw_text: str) tuple[str, bool][source]
additional_field_help(field: wtforms.Field, length_limit: int = 54) str | None[source]

Returns the field description in modified form if the description should be rendered separately in the field macro.

class form.core.Fieldset(label: str | None, fields: Iterable[Field])[source]

Defines a fieldset with a list of fields.

property is_visible: bool[source]
property non_empty_fields: dict[str, CallableProxyType[Field]][source]

Returns only the fields which are not empty.

fields: dict[str, CallableProxyType[Field]][source]
__len__() int[source]
__getitem__(key: str) CallableProxyType[Field][source]
class form.core.FieldDependency(*kwargs: object)[source]

Defines a dependency to a field. The given field(s) must have the given choice for this dependency to be fulfilled.

It’s possible to depend on NOT the given value by preceeding it with a ‘!’:

FieldDependency(‘field_1’, ‘!choice_1’)

To depend on more than one field, add the field_id’s and choices to the constructor:

FieldDependency(‘field_1’, ‘choice_1’) FieldDependency(‘field_1’, ‘choice_1’, ‘field_2’, ‘choice_2’)

property field_id: str[source]
property html_data: dict[str, str][source]
dependencies: list[DependencyDict][source]
fulfilled(form: Form, field: wtforms.Field) bool[source]
unfulfilled(form: Form, field: wtforms.Field) bool[source]
class form.core.Pricing(rules: onegov.form.types.PricingRules)[source]

Defines pricing on a field, returning the correct price for the field depending on its rule.

property has_payment_rule: bool[source]
price(field: wtforms.Field) onegov.pay.Price | None[source]
form.core.merge_forms(form: type[_FormT], /, *forms: type[Form]) type[_FormT][source]

Takes a list of forms and merges them.

In doing so, a new class is created which inherits from all the forms in the default method resolution order. So the first class will override fields in the second class and so on.

So this method is basically the same as:

class Merged(*forms):
    pass

With one crucial difference, the order of the fields is as follows:

First, the fields from the first form are rendered, then the fields from the second form and so on. This is not the case if you merge the forms by simple class inheritance, as each form has it’s own internal field order, which when merged leads to unexpected results.

form.core.enforce_order(form_class: type[_FormT], fields_in_order: Iterable[str]) type[_FormT][source]

Takes a list of fields used in a form_class and enforces the order of those fields.

If not all fields in the form are given, the resulting order is undefined.

form.core.move_fields(form_class: type[_FormT], fields: Collection[str], after: str | None) type[_FormT][source]

Reorders the given fields (given by name) by inserting them directly after the given field.

If after is None, the fields are moved to the end.