Skip to main content
Ctrl+K
fairdm 0.3.1 documentation - Home fairdm 0.3.1 documentation - Home
    • Developers
    • Administrators
    • Users
    • What FairDM is for
    • FAIR data and research data infrastructure
    • The technology stack
    • The core data model
    • How sample and measurement types are stored
    • Controlled vocabularies
    • Configuration over code
    • Why complete metadata matters
    • How access to a record is decided
    • Why FairDM records contributors
    • How contributor accounts and credits work
    • How a profile is claimed
    • How FairDM configures a portal
    • Who is asked to agree to a legal document
    • How locations are stored and protected
    • Dataset publication, DOIs and DataCite metadata
    • Glossary
    • Framework Contributors
    • Architecture Decision Records
    • Roadmap — FairDM
    • Changelog
  • GitHub
  • GitHub
  • Developers
  • Administrators
  • Users
  • What FairDM is for
  • FAIR data and research data infrastructure
  • The technology stack
  • The core data model
  • How sample and measurement types are stored
  • Controlled vocabularies
  • Configuration over code
  • Why complete metadata matters
  • How access to a record is decided
  • Why FairDM records contributors
  • How contributor accounts and credits work
  • How a profile is claimed
  • How FairDM configures a portal
  • Who is asked to agree to a legal document
  • How locations are stored and protected
  • Dataset publication, DOIs and DataCite metadata
  • Glossary
  • Framework Contributors
  • Architecture Decision Records
  • Roadmap — FairDM
  • Changelog
  • GitHub
  • GitHub

Section Navigation

  • ADR 0001 — Environment overrides are found by existence, beside a known anchor
  • ADR 0002 — Configuration checks run automatically in production, and nowhere else
  • ADR 0003 — The baseline ships no working default for a security-critical value
  • ADR 0004 — A portal’s apps are registered ahead of FairDM’s
  • ADR 0005 — A measurement type nominates its value; the base reports and formats it
  • ADR 0006 — What the registry generates carries the framework’s mixins
  • ADR 0007 — Every record has a page of its own
  • ADR 0008 — One editing page per record, with its related rows inline
  • ADR 0009 — A form’s default and a model’s default may legitimately differ
  • ADR 0010 — Record addresses name the record type in the plural
  • ADR 0011 — One navigation entry per collection of pages
  • ADR 0012 — Every page states its own access rules
  • ADR 0013 — A listing shows published records only, for everyone
  • ADR 0014 — Publication is a separate flag from visibility
  • ADR 0015 — A record’s own dataset decides, and a row never links past it
  • ADR 0016 — The framework indexes the fields it searches by default
  • ADR 0017 — Listings are addressed and named apart from records
  • ADR 0018 — Publication is a queryset method, not a default manager
  • ADR 0019 — A portal role is the unit of portal-wide rights
  • ADR 0020 — A missing role is answered four ways, and never by blocking repair
  • ADR 0021 — Profile claims and merges belong to a named role, not to superusers
  • ADR 0022 — Development accounts are a command that refuses, not a fixture that loads
  • ADR 0023 — An overview page is extended through blocks, plugin methods and type templates
  • ADR 0024 — The right to edit a profile is asked of the record
  • ADR 0025 — A level on the contribution decides rights over a core record
  • ADR 0026: A record’s editing pages are six shared pages
  • ADR 0027 — Records refer to each other by short identifier, never by database number
  • ADR 0028 — API tokens are created on the account pages, never exchanged for a password
  • ADR 0029 — People and organizations have their own API endpoints
  • ADR 0030 — A credit on a record carries what DataCite asks of a creator
  • ADR 0031 — Portals run on PostgreSQL with PostGIS
  • ADR 0032 — A location is a value on each record, not a shared row
  • ADR 0033 — A measurement borrows its sample’s location only for a viewer who may open the sample
  • ADR 0034 — Portals build on the base images FairDM publishes
  • ADR 0035 — FairDM does not compress static files
  • ADR 0036 — FairDM declares the image and database a portal runs on
  • ADR 0037 — Autocomplete fields are built on django-tomselect
  • ADR 0038 — Each autocomplete scope is its own view
  • ADR 0039 — Autocomplete addresses are limited per caller
  • ADR 0040 — Backup schedules are periodic tasks
  • ADR 0041 — Backups are encrypted to a public key
  • Architecture Decision Records
  • ADR 0008 — One editing page per record, with its related rows inline

ADR 0008 — One editing page per record, with its related rows inline#

Status: superseded by ADR 0026

Decision#

A record has exactly one page offering its own attributes, and that page also edits the related rows that belong to the record rather than describing it — its dates and its external identifiers, each as a row set on the same form, saved in the same submission.

The page is registered against the record as an additional view of the record’s own page, not as a separate route. Prose about the record — its abstract and the other passages — is the exception and keeps a page of its own, because it is a fixed set of labelled areas rather than rows to add and remove.

The row sets are built with the interface layer’s own inline formsets (mvp.views.inline). The project’s pages no longer reach for django-extra-views.

Why#

There were two editing pages, and only one of them could be reached. A registered tab offered three of the project’s fields; a separate route offered the full set, carried the tests, and had no link pointing at it anywhere in the portal. Two surfaces editing one record is a standing invitation for them to drift, and the one a user could actually find was the poorer of the two.

A record’s dates are a row set even when there are only two of them. A project has a start and an end, and modelling those as two ordinary fields would have been simpler for the project alone. It would also have been the wrong shape for every record type that follows: datasets, samples and measurements each have several dates, and their vocabularies differ. Adding a date type should be a row a user adds, not a field a developer inserts.

The same editing interaction across record types is worth more than a per-record optimisation. Projects, datasets, samples and measurements are edited by the same people, and a researcher who has learned one record’s editing page should recognise the next. That argument is what settles the date question above, and it is the reason the row-set declaration and the date-ordering rule are shared pieces parameterised per record rather than written out per record.

The one thing deliberately not shared is the permission each page states. Deriving it from the model breaks on the polymorphic record types, where a concrete sample would derive a permission nothing grants.

Revisit if#

A record type appears whose related rows are numerous enough that editing them alongside the record’s own fields makes the page unusable — a hundred identifiers, say. The answer then is a page of its own for that row set on that record type, not a different mechanism for all of them.

previous

ADR 0007 — Every record has a page of its own

next

ADR 0009 — A form’s default and a model’s default may legitimately differ

On this page
  • Decision
  • Why
  • Revisit if

© Copyright 2026, Samuel Jennings.

Built with the PyData Sphinx Theme 0.21.0.