Version 23 (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" table = db.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 a IS_NULL_OR
(IS_EMPTY_OR
) validator in the S3ReusableField
when generating the Field
instance, you can use the special attribute empty
:
resourcename = "mytable" tablename = "%s_%s" % (module, resourcename) table = db.define_table(tablename, ..., person_id(empty=False), # inserts the person_id Field, but removes IS_NULL_OR from .requires ...)
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" table = db.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" table = db.define_table(tablename, ..., # Specify the widget explicitly: organisation_id(widget=MyCustomWidget()), ... )
...or enforce the web2py standard widget for the field type:
tablename = "my_table" table = db.define_table(tablename, ..., # Enforce web2py standard widget for the field type: organisation_id(widget=None), ... )