wiki:S3/S3ReusableField

Version 31 (modified by Dominic König, 10 years ago) ( diff )

--

Developer Guidelines | S3ReusableField

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

Besides the normal "widget" attribute to specify a form widget for the resuable field, it is also possible to specify multiple possible widget alternatives, and then apply them in the instances by name.

To do so, use the "widgets" (plural!) attribute.

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.

NB: one should avoid having both "widget" and "widgets" in the same S3ReusableField. However, where both are present, "widget" overrides the "default" alternative in "widgets".

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),
                  ...
                  )

DeveloperGuidelines

Note: See TracWiki for help on using the wiki.