| Version 27 (modified by , 11 years ago) ( diff ) |
|---|
Developer Guidelines | S3ReusableField
Table of Contents
S3ReusableField
S3ReusableField is a DRY helper class for re-usable Field definitions.
Define a S3ReusableField
A S3ReusableField is to be defined like a normal Field (though outside any Table definitions):
person_id = S3ReusableField("person_id", "reference pr_person",
sortby = ["first_name", "middle_name", "last_name"],
requires = IS_NULL_OR(IS_ONE_OF(db, "pr_person.id",
person_represent,
orderby="pr_person.first_name",
sort=True,
error_message="Person must be specified!")),
represent = pr_person_represent,
label = T("Person"),
comment = pr_person_id_comment,
ondelete = "RESTRICT",
widget = S3PersonAutocompleteWidget())
This definition does not create a Field instance, but just holds the parameters.
Use S3ReusableFields in Table Definitions
To use this in a Table definition, just call the S3ReusableField object to generate a Field instance:
tablename = "mytable"
self.define_table(tablename,
...,
# Insert a Field("person_id") with the pre-defined parameters:
person_id(),
...)
Note: If the S3ReusableField contains the sortby attribute, then a FieldS3 instance is generated instead of Field
Override Field Attributes
You can override the name and any attributes when generating the Field instance, by just re-specifying them:
tablename = mytable"
self.define_table(tablename,
...,
# Insert a Field("reporter") with the attributes from person_id:
person_id("reporter",
# also override the label:
label=T("Reporter"),
),
...)
Deactivate IS_EMPTY_OR
To deactivate an IS_EMPTY_OR validator in the S3ReusableField when generating the Field instance, you can use the special attribute empty:
tablename = "my_table"
self.define_table(tablename,
...,
# Inserts the person_id Field, but remove IS_EMPTY_OR from .requires:
person_id(empty=False),
...)
Multiple Widgets
It is possible to specify multiple possible widget alternatives in the S3ReusableField, and then apply them by name.
Example:
organisation_id = S3ReusableField("organisation_id", "reference org_organisation",
requires = IS_EMPTY_OR(IS_ONE_OF(db, "org_organisation.id",
org_organisation_represent)),
represent = org_organisation_represent,
label = T("Organisation"),
widgets = {"default": S3OrganisationAutocompleteWidget(default_from_profile=True),
"hierarchical": S3HierarchyWidget(lookup = "org_organisation",
represent = org_organisation_represent,
multiple = False,
leafonly = False,
),
},
)
Without override or explicit choice, the "default" widget would be used in Field instances.
To choose a widget by name:
tablename = "my_table"
self.define_table(tablename,
...,
# Choose the "hierarchical" widget for this instance:
organisation_id(widget="hierarchical"),
...
)
This is especially useful if the choice of the widget depends on a deployment setting.
However, every instance can still override all possible alternatives:
tablename = "my_table"
self.define_table(tablename,
...,
# Specify the widget explicitly:
organisation_id(widget=MyCustomWidget()),
...
)
...or enforce the web2py standard widget for the field type:
tablename = "my_table"
self.define_table(tablename,
...,
# Enforce web2py standard widget for the field type:
organisation_id(widget=None),
...
)

