wiki:S3/S3ReusableField

Version 23 (modified by Dominic König, 11 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"
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),
                        ...
                        )

DeveloperGuidelines

Note: See TracWiki for help on using the wiki.