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:
- 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 theschema
.
- 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 casemodel_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
isFalse
.See also
set_readonly()
andis_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. Howeverrequired_fields
keeps track of any “overrides” per field.See also
set_required()
andis_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 alsorender_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, viaget_model_fields()
.Otherwise
None
is returned.
- get_global_errors()[source]¶
Returns a list of “global” (not field-level) error messages for the form.
See also
has_global_errors()
.- Returns:
List of error messages (possibly empty).
- 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 infields
as well as the Deform schema.It also converts each as needed, to ensure it is JSON-serializable.
- Returns:
Dict of field/value items.
- has_global_errors()[source]¶
Convenience function to check if the form has any “global” (not field-level) errors.
See also
get_global_errors()
.- Returns:
True
if global errors present, elseFalse
.
- 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; otherwiseNone
.
- make_widget(widget_type, **kwargs)[source]¶
Make and return a new field widget of the given type.
This has built-in support for the following types (although subclass can override as needed):
'notes'
=>NotesWidget
See also
set_widget()
which may call this method automatically.- Parameters:
widget_type – Which of the above (or custom) widget type to create.
**kwargs – Remaining kwargs are passed as-is to the widget factory.
- Returns:
New widget instance, or
None
if e.g. it could not determine how to create the widget.
- 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
andfields
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_default_widgets()[source]¶
Set default field widgets, where applicable.
This will add new entries to
widgets
for columns whose data type implies a default widget should be used. This is generally only possible ifmodel_class
is set to a valid SQLAlchemy mapped class.As of writing this only looks for
sqlalchemy.types.DateTime
fields and if any are found, they are configured to useWuttaDateTimeWidget()
.
- set_fields(fields)[source]¶
Explicitly set the list of form fields.
This will overwrite
fields
with a newFieldList
instance.- Parameters:
fields – List of string field names.
- set_grid(key, grid)[source]¶
Establish a grid to be displayed for a field. This uses a
GridWidget
to wrap the rendered grid.- Parameters:
key – Name of field.
widget –
Grid
instance, pre-configured and (usually) with data.
- 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 acolander:colander.SchemaType
instance.
If
nodeinfo
is a proper node instance, it will be used as-is. Otherwise anObjectNode
instance will be constructed usingnodeinfo
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 viareadonly_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 viarequired_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, **kwargs)[source]¶
Set/override the widget for a field.
You can specify a widget instance or else a named “type” of widget, in which case that is passed along to
make_widget()
.- Parameters:
key – Name of field.
widget – Either a
deform.widget.Widget
instance, or else a widget “type” name.**kwargs – Any remaining kwargs are passed along to
make_widget()
- if applicable.
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 novalidated
attribute. In that case you should inspect the form errors to learn/display what went wrong for the user’s sake. See alsoget_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, allreadonly_fields
will be removed from theschema
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
.