wuttaweb.forms.base

Base form classes

class wuttaweb.forms.base.Form(request, fields=None, schema=None, model_class=None, model_instance=None, nodes={}, widgets={}, validators={}, defaults={}, readonly=False, readonly_fields=[], required_fields={}, labels={}, action_url=None, cancel_url=None, cancel_url_fallback=None, vue_tagname='wutta-form', align_buttons_right=False, auto_disable_submit=True, button_label_submit='Save', button_icon_submit='save', button_type_submit='is-primary', show_button_reset=False, show_button_cancel=True, button_label_cancel='Cancel', auto_disable_cancel=True)[source]

Base class for all forms.

Parameters:
  • request – Reference to current request object.

  • fields – List of field names for the form. This is optional; if not specified an attempt will be made to deduce the list automatically. See also fields.

  • schema – Colander-based schema object for the form. This is optional; if not specified an attempt will be made to construct one automatically. See also get_schema().

  • labels – Optional dict of default field labels.

Note

Some parameters are not explicitly described above. However their corresponding attributes are described below.

Form instances contain the following attributes:

request

Reference to current request object.

fields

FieldList instance containing string field names for the form. By default, fields will appear in the same order as they are in this list.

See also set_fields().

schema

colander.Schema object for the form. This is optional; if not specified an attempt will be made to construct one automatically.

See also get_schema().

model_class

Model class for the form, if applicable. When set, this is usually a SQLAlchemy mapped class. This (or model_instance) may be used instead of specifying the schema.

model_instance

Optional instance from which initial form data should be obtained. In simple cases this might be a dict, or maybe an instance of model_class.

Note that this also may be used instead of specifying the schema, if the instance belongs to a class which is SQLAlchemy-mapped. (In that case model_class can be determined automatically.)

nodes

Dict of node overrides, used to construct the form in get_schema().

See also set_node().

widgets

Dict of widget overrides, used to construct the form in get_schema().

See also set_widget().

validators

Dict of node validators, used to construct the form in get_schema().

See also set_validator().

defaults

Dict of default field values, used to construct the form in get_schema().

See also set_default().

readonly

Boolean indicating the form does not allow submit. In practice this means there will not even be a <form> tag involved.

Default for this is False in which case the <form> tag will exist and submit is allowed.

readonly_fields

A set of field names which should be readonly. Each will still be rendered but with static value text and no widget.

This is only applicable if readonly is False.

See also set_readonly() and is_readonly().

required_fields

A dict of “required” field flags. Keys are field names, and values are boolean flags indicating whether the field is required.

Depending on schema, some fields may be “(not) required” by default. However required_fields keeps track of any “overrides” per field.

See also set_required() and is_required().

action_url

String URL to which the form should be submitted, if applicable.

cancel_url

String URL to which the Cancel button should “always” redirect, if applicable.

Code should not access this directly, but instead call get_cancel_url().

cancel_url_fallback

String URL to which the Cancel button should redirect, if referrer cannot be determined from request.

Code should not access this directly, but instead call get_cancel_url().

vue_tagname

String name for Vue component tag. By default this is 'wutta-form'. See also render_vue_tag().

See also vue_component.

align_buttons_right

Flag indicating whether the buttons (submit, cancel etc.) should be aligned to the right of the area below the form. If not set, the buttons are left-aligned.

auto_disable_submit

Flag indicating whether the submit button should be auto-disabled, whenever the form is submitted.

button_label_submit

String label for the form submit button. Default is "Save".

button_icon_submit

String icon name for the form submit button. Default is 'save'.

button_type_submit

Buefy type for the submit button. Default is 'is-primary', so for example:

<b-button type="is-primary"
          native-type="submit">
  Save
</b-button>

See also the Buefy docs.

show_button_reset

Flag indicating whether a Reset button should be shown. Default is False.

show_button_cancel

Flag indicating whether a Cancel button should be shown. Default is True.

button_label_cancel

String label for the form cancel button. Default is "Cancel".

auto_disable_cancel

Flag indicating whether the cancel button should be auto-disabled, whenever the button is clicked. Default is True.

validated

If the validate() method was called, and it succeeded, this will be set to the validated data dict.

Note that in all other cases, this attribute may not exist.

append(*keys)[source]

Add some fields(s) to the form.

This is a convenience to allow adding multiple fields at once:

form.append('first_field',
            'second_field',
            'third_field')

It will add each field to fields.

get_cancel_url()[source]

Returns the URL for the Cancel button.

If cancel_url is set, its value is returned.

Or, if the referrer can be deduced from the request, that is returned.

Or, if cancel_url_fallback is set, that value is returned.

As a last resort the “default” URL from get_referrer() is returned.

get_deform()[source]

Return the deform.Form instance for the form, generating it automatically if necessary.

get_field_errors(field)[source]

Return a list of error messages for the given field.

Not useful unless a call to validate() failed.

get_fields()[source]

Returns the official list of field names for the form, or None.

If fields is set and non-empty, it is returned.

Or, if schema is set, the field list is derived from that.

Or, if model_class is set, the field list is derived from that, via get_model_fields().

Otherwise None is returned.

get_label(key)[source]

Get the label for given field name.

Note that this will always return a string, auto-generating the label if needed.

See also set_label().

get_model_fields(model_class=None)[source]

This method is a shortcut which calls get_model_fields().

Parameters:

model_class – Optional model class for which to return fields. If not set, the form’s model_class is assumed.

get_schema()[source]

Return the colander.Schema object for the form, generating it automatically if necessary.

Note that if schema is already set, that will be returned as-is.

get_vue_model_data()[source]

Returns a dict with form model data. Values may be nested depending on the types of fields contained in the form.

This collects the cstruct values for all fields which are present both in fields as well as the Deform schema.

It also converts each as needed, to ensure it is JSON-serializable.

Returns:

Dict of field/value items.

is_readonly(key)[source]

Returns boolean indicating if the given field is marked as readonly.

See also set_readonly().

Parameters:

key – Field key/name as string.

is_required(key)[source]

Returns boolean indicating if the given field is marked as required.

See also set_required().

Parameters:

key – Field key/name as string.

Returns:

Value for the flag from required_fields if present; otherwise None.

remove(*keys)[source]

Remove some fields(s) from the form.

This is a convenience to allow removal of multiple fields at once:

form.remove('first_field',
            'second_field',
            'third_field')

It will remove each field from fields.

render_vue_field(fieldname, readonly=None, **kwargs)[source]

Render the given field completely, i.e. <b-field> wrapper with label and containing a widget.

Actual output will depend on the field attributes etc. Typical output might look like:

<b-field label="Foo"
         horizontal
         type="is-danger"
         message="something went wrong!">
   <!-- widget element(s) -->
</b-field>

Warning

Any **kwargs received from caller are ignored by this method. For now they are allowed, for sake of backwawrd compatibility. This may change in the future.

render_vue_finalize()[source]

Render the Vue “finalize” script for the form.

By default this simply returns:

<script>
  WuttaForm.data = function() { return WuttaFormData }
  Vue.component('wutta-form', WuttaForm)
</script>

The actual output may depend on various form attributes, in particular vue_tagname.

render_vue_tag(**kwargs)[source]

Render the Vue component tag for the form.

By default this simply returns:

<wutta-form></wutta-form>

The actual output will depend on various form attributes, in particular vue_tagname.

render_vue_template(template='/forms/vue_template.mako', **context)[source]

Render the Vue template block for the form.

This returns something like:

<script type="text/x-template" id="wutta-form-template">
  <form>
    <!-- fields etc. -->
  </form>
</script>

<script>
    WuttaFormData = {}
    WuttaForm = {
        template: 'wutta-form-template',
    }
</script>

Actual output will of course depend on form attributes, i.e. vue_tagname and fields list etc.

Parameters:

template – Path to Mako template which is used to render the output.

set_default(key, value)[source]

Set/override the default value for a field.

Parameters:
  • key – Name of field.

  • validator – Default value for the field.

Default value overrides are tracked via defaults.

set_fields(fields)[source]

Explicitly set the list of form fields.

This will overwrite fields with a new FieldList instance.

Parameters:

fields – List of string field names.

set_label(key, label)[source]

Set the label for given field name.

See also get_label().

set_node(key, nodeinfo, **kwargs)[source]

Set/override the node for a field.

Parameters:
  • key – Name of field.

  • nodeinfo – Should be either a colander.SchemaNode instance, or else a colander:colander.SchemaType instance.

If nodeinfo is a proper node instance, it will be used as-is. Otherwise an ObjectNode instance will be constructed using nodeinfo as the type (typ).

Node overrides are tracked via nodes.

set_readonly(key, readonly=True)[source]

Enable or disable the “readonly” flag for a given field.

When a field is marked readonly, it will be shown in the form but there will be no editable widget. The field is skipped over (not saved) when form is submitted.

See also is_readonly(); this is tracked via readonly_fields.

Parameters:
  • key – String key (fieldname) for the field.

  • readonly – New readonly flag for the field.

set_required(key, required=True)[source]

Enable or disable the “required” flag for a given field.

When a field is marked required, a value must be provided or else it fails validation.

In practice if a field is “not required” then a default “empty” value is assumed, should the user not provide one.

See also is_required(); this is tracked via required_fields.

Parameters:
  • key – String key (fieldname) for the field.

  • required – New required flag for the field. Usually a boolean, but may also be None to remove any flag and revert to default behavior for the field.

set_validator(key, validator)[source]

Set/override the validator for a field, or the form.

Parameters:
  • key – Name of field. This may also be None in which case the validator will apply to the whole form instead of a field.

  • validator

    Callable which accepts (node, value) args. For instance:

    def validate_foo(node, value):
        if value == 42:
            node.raise_invalid("42 is not allowed!")
    
    form = Form(fields=['foo', 'bar'])
    
    form.set_validator('foo', validate_foo)
    

Validator overrides are tracked via validators.

set_widget(key, widget)[source]

Set/override the widget for a field.

Parameters:

Widget overrides are tracked via widgets.

validate()[source]

Try to validate the form, using data from the request.

Uses get_form_data() to retrieve the form data from POST or JSON body.

If the form data is valid, the data dict is returned. This data dict is also made available on the form object via the validated attribute.

However if the data is not valid, False is returned, and there will be no validated attribute. In that case you should inspect the form errors to learn/display what went wrong for the user’s sake. See also get_field_errors().

This uses deform.Field.validate() under the hood.

Warning

Calling validate() on some forms will cause the underlying Deform and Colander structures to mutate. In particular, all readonly_fields will be removed from the schema to ensure they are not involved in the validation.

Returns:

Data dict, or False.

property vue_component

String name for the Vue component, e.g. 'WuttaForm'.

This is a generated value based on vue_tagname.