How to customise a generated component#
A registered type gets six generated components: a form, a table, a filter set, a serializer, an import and export resource and an administration page. You change one of them when its fields, its class or its behaviour is not what the type needs, and the other five stay as they are.
Before you start#
You need a registered type. See How to register a sample or measurement type. This guide uses PlantSample, a sample type in an app named fieldwork, with the fields species, collected_on and notes. Use the first of the three sections below that does what you need.
Give one component its own fields#
Add the component’s field list to the configuration. Here the table shows three columns while every other component still uses
fields.# fieldwork/config.py from fairdm.core.sample.config import BaseSampleConfiguration from fairdm.registry import register from .models import PlantSample @register class PlantSampleConfig(BaseSampleConfiguration): model = PlantSample fields = [ *BaseSampleConfiguration.fields, "species", "collected_on", "notes", ] table_fields = ["name", "species", "collected_on"]
Restart the portal and open the type’s listing.
The table has the columns you listed, with the dataset icon, Latitude and Longitude that every sample table carries. The names of the lists are form_fields, table_fields, filterset_fields, serializer_fields, resource_fields and admin_list_display. To leave a field out of every component, add its name to exclude instead. See Component field lists.
Replace a component with a class of your own#
Write the class on the base that the component builds on. The base tables are
SampleTableandMeasurementTableinfairdm.contrib.collections.tables. Extend the base’sMetaso the table keeps its classes, its column order and its sorting.# fieldwork/tables.py from fairdm.contrib.collections.tables import SampleTable from .models import PlantSample class PlantSampleTable(SampleTable): class Meta(SampleTable.Meta): model = PlantSample fields = ["id", "dataset", "name", "species", "collected_on"] def render_species(self, value): return value.upper()
Name the class in the configuration, and remove the same component’s field list. A component can have a field list or a class, and the registry refuses both.
# fieldwork/config.py from fairdm.core.sample.config import BaseSampleConfiguration from fairdm.registry import register from .models import PlantSample from .tables import PlantSampleTable @register class PlantSampleConfig(BaseSampleConfiguration): model = PlantSample fields = [ *BaseSampleConfiguration.fields, "species", "collected_on", "notes", ] table_class = PlantSampleTable
If the configuration extends
BaseMeasurementConfiguration, set the component’s own list toNoneas well. That base setsform_fields,table_fieldsandfilterset_fields, and the registry counts an inherited list.table_fields = None table_class = LeafAreaMeasurementTable
Restart the portal and open the type’s listing.
The table shows the species in capitals. A class option also accepts a dotted path such as "fieldwork.tables.PlantSampleTable". Each component builds on its own base, which the reference lists under Component classes.
Build a component in code#
Use this when a declaration cannot say what you need, because the answer has to be worked out.
Override the component’s accessor in the configuration. Here the filter set offers only the fields in
FILTERABLE, chosen from the fields the filter set would use. A field added tofieldslater does not gain a filter by accident.# fieldwork/config.py from fairdm.core.sample.config import BaseSampleConfiguration from fairdm.registry import register from fairdm.registry.factories import FilterFactory from .models import PlantSample @register class PlantSampleConfig(BaseSampleConfiguration): model = PlantSample fields = [ *BaseSampleConfiguration.fields, "species", "collected_on", "notes", ] FILTERABLE = {"species", "collected_on"} def get_filterset_class(self): names = [ name for name in self.resolve_fields("filterset") if name in self.FILTERABLE ] return FilterFactory( model=self.model, fields=names, search_fields=self.get_search_fields(), ).generate()
Restart the portal and open the type’s listing.
The filter panel offers Species and Collected on. Every part of the framework reaches the filter set through get_filterset_class(), so the listing and the API both receive yours. The accessors are on Methods.
To change the administration page of a measurement type, see How to customise the admin for a measurement type. To change a form or a filter set with the framework’s mixins, see How to customise a sample form and How to write a custom form or filter for a measurement type.