fairdm.registry.config#

Model configuration: how a portal declares the way its model appears.

A portal writes a ModelConfiguration subclass, names the model and the fields that matter, and the framework supplies six component classes from it. There are three tiers of customisation, in increasing order of effort:

  1. declare a field list, shared or per component;

  2. declare a custom class for one component;

  3. override that component’s get_<component>_class() method.

Every caller inside the framework reaches a component through its accessor, so an override at tier 3 is what the whole framework receives. Nothing is cached: an accessor builds or resolves its class on every call, which is what Django’s own ModelFormMixin.get_form_class() does.

Module Contents#

Classes#

Authority

The authority that created or maintains a data model.

Citation

A citation for a data model.

ModelMetadata

Structured metadata describing a registered model.

Component

One row of the component table.

ModelConfiguration

How one model appears across every framework surface.

SampleConfig

Configuration for a Sample subclass. Named for clarity at the call site.

MeasurementConfig

Configuration for a Measurement subclass. Named for clarity at the call site.

Functions#

flatten_fields

Flatten a field list that groups names in tuples for layout.

Data#

COMPONENTS

Every component the registry produces, and where its configuration lives.

API#

class Authority[source]#

The authority that created or maintains a data model.

Attributes: name: The full name of the authority. Required. Accepts a lazy translation as well as a plain string, so an app config can declare its authority with gettext_lazy before the translations load. short_name: An abbreviated name for the authority. website: The authority’s website URL.

name: str | django.utils.functional.Promise#

None

short_name: str = <Multiline-String>#
website: str = <Multiline-String>#
class Citation[source]#

A citation for a data model.

Attributes: text: The full citation text. doi: The DOI for the citation.

text: str = <Multiline-String>#
doi: str = <Multiline-String>#
class ModelMetadata[source]#

Structured metadata describing a registered model.

Holds FAIR-compliant metadata about a Sample or Measurement model, so that a registered model can describe and credit itself.

description: str = <Multiline-String>#
authority: fairdm.registry.config.Authority | None#

None

keywords: list[str]#

‘field(…)’

repository_url: str = <Multiline-String>#
citation: fairdm.registry.config.Citation | None#

None

maintainer: str = <Multiline-String>#
maintainer_email: str = <Multiline-String>#
class Component[source]#

Bases: typing.NamedTuple

One row of the component table.

Attributes: fields_attr: The configuration attribute holding the component’s own field list. class_attr: The configuration attribute holding a supplied class. base: The class a supplied class must subclass. factory: The name of the generator in fairdm.registry.factories. default_exclude: Names left out when the component is built from the framework’s own choice of fields, because they are no use there. A field list the portal declares is never filtered by it.

fields_attr: str#

None

class_attr: str#

None

base: type | None#

None

factory: str#

None

default_exclude: tuple[str, ...]#

()

COMPONENTS: dict[str, fairdm.registry.config.Component]#

None

Every component the registry produces, and where its configuration lives.

base is None for the two components whose base class cannot be imported at module scope: the serializer’s base comes from Django REST Framework and the admin’s from django.contrib.admin, both of which import app code.

flatten_fields(fields: collections.abc.Sequence[Any] | None) → list[str][source]#

Flatten a field list that groups names in tuples for layout.

A grouped list and a plain one produce the same fields, so grouping is free for a portal to use and invisible to every generator.

Args: fields: Field names, possibly grouped in tuples or nested lists.

Returns: The flat list of field names, empty when fields is empty or None.

class ModelConfiguration(model: type[models.Model] | None = None, **overrides: Any)[source]#

How one model appears across every framework surface.

Written as a subclass declaring class attributes, the way Meta and ModelAdmin are written::

@fairdm.register
class RockSampleConfig(ModelConfiguration):
    model = RockSample
    fields = ["name", "location", "date_collected"]

Declare a component’s own field list where it differs from the rest::

    table_fields = ["name", "location", "contributor"]

Supply a class to replace one component outright::

    table_class = RockSampleTable

Or override its accessor when a field list cannot say what you need::

    def get_table_class(self):
        return build_table(self.model)

Declaring both a component’s field list and its class is refused at registration, following Django’s rule for fields and form_class.

The configuration is validated when it is built, so a misconfigured portal stops at import rather than serving a broken page.

Attributes: model: The Django model this configures. A concrete Sample or Measurement subclass. Declared non-optional because every method may rely on it: the default of None exists only so that a subclass can supply it, and _validate_model refuses a configuration that reaches the end of construction without one. metadata: Structured metadata about the model. fields: Field list inherited by every component that declares none of its own. Names may use Django’s double-underscore paths, and may be grouped in tuples for layout. An empty list means the framework decides. exclude: Names to leave out of every component. search_fields: Field paths the listing’s q filter matches. None (the default) resolves to ["name"] via get_search_fields(). Every entry must resolve to a text field, CharField or TextField, the same test AdminFactory._get_search_fields applies when it picks the admin’s own search fields. A numeric, boolean or date field is refused at import rather than raising on a visitor’s first search. form_fields: Field list for the form component alone. table_fields: Field list for the table component alone. filterset_fields: Field list for the filterset component alone. serializer_fields: Field list for the serializer component alone. resource_fields: Field list for the import and export resource alone. admin_list_display: Field list for the admin component alone. form_class: A form class, or its dotted path, replacing the generated one. table_class: A table class, or its dotted path, replacing the generated one. filterset_class: A filterset class, or its dotted path, replacing the generated one. serializer_class: A serializer class, or its dotted path, replacing the generated one. resource_class: A resource class, or its dotted path, replacing the generated one. admin_class: An admin class, or its dotted path, replacing the generated one. display_name: Human-readable name, defaulting to the model’s verbose name. description: Description of this model type.

Args: model: The model to configure. Passed positionally, as registry.register does, or by keyword alongside any other configuration attribute. **overrides: Configuration attributes to set on this instance.

Raises: TypeError: An override names an attribute that cannot be overridden.

Initialization

model: type[models.Model]#

None

metadata: fairdm.registry.config.ModelMetadata | None#

None

fields: list[Any]#

[]

exclude: list[str]#

[]

search_fields: list[str] | None#

None

form_fields: list[Any] | None#

None

table_fields: list[Any] | None#

None

filterset_fields: list[Any] | None#

None

serializer_fields: list[Any] | None#

None

resource_fields: list[Any] | None#

None

admin_list_display: list[Any] | None#

None

form_class: type[django.forms.ModelForm] | str | None#

None

table_class: type[django_tables2.Table] | str | None#

None

filterset_class: type[django_filters.FilterSet] | str | None#

None

serializer_class: type[ModelSerializer] | str | None#

None

resource_class: type[import_export.resources.ModelResource] | str | None#

None

admin_class: type[ModelAdmin] | str | None#

None

display_name: str = <Multiline-String>#
description: str = <Multiline-String>#
classmethod get_default_fields(model: type[models.Model]) → list[str][source]#

Return the framework’s own choice of fields for a model.

Delegates to FieldInspector so the API, the admin and every generated component agree on one default.

Args: model: The model to choose fields for.

Returns: The default field names.

resolve_fields(component: str) → list[str][source]#

Return the field list one component is built from.

A component’s own list wins, then the shared list, then the framework’s defaults. Grouping tuples are flattened, and anything in exclude is dropped.

Args: component: The component name, a key of COMPONENTS.

Returns: The flat list of field names for that component.

get_search_fields() → list[str][source]#

Return the fields the listing’s q filter searches, ["name"] by default.

get_form_class() → type[django.forms.ModelForm][source]#

Return the ModelForm for this model. Override to build your own.

get_table_class() → type[django_tables2.Table][source]#

Return the django-tables2 Table for this model. Override to replace it.

get_filterset_class() → type[django_filters.FilterSet][source]#

Return the django-filter FilterSet for this model, searching get_search_fields().

Override to replace it.

get_serializer_class() → type[ModelSerializer][source]#

Return the REST serializer for this model. Override to build your own.

get_resource_class() → type[import_export.resources.ModelResource][source]#

Return the import and export resource. Override to build your own.

get_admin_class() → type[ModelAdmin][source]#

Return the Django admin class for this model. Override to build your own.

get_display_name() → str[source]#

Return the human-readable name for this model.

get_description() → str[source]#

Return the description for this model.

get_slug() → str[source]#

Return the URL-safe name for this model, used in routes and view names.

get_verbose_name() → str[source]#

Return the model’s singular verbose name.

get_verbose_name_plural() → str[source]#

Return the model’s plural verbose name.

class SampleConfig(model: type[models.Model] | None = None, **overrides: Any)[source]#

Bases: fairdm.registry.config.ModelConfiguration

Configuration for a Sample subclass. Named for clarity at the call site.

Initialization

class MeasurementConfig(model: type[models.Model] | None = None, **overrides: Any)[source]#

Bases: fairdm.registry.config.ModelConfiguration

Configuration for a Measurement subclass. Named for clarity at the call site.

Initialization