Aller au contenu

Models

Status: Placeholder — to be developed. Last reviewed:Reference structural sibling: guidelines/ui/forms.md (component-style sectioning + length).

Scope (when this guideline lands)

Conventions for Django models: which abstract base to inherit from, field naming, choices vs enums, __str__ style, Meta ordering, soft-delete handling, when a custom manager is justified.

Out of scope (cross-refs)

  • Migration generation and reviewguidelines/backend/migrations.md (placeholder).
  • Admin registration / list_displayguidelines/backend/admin.md (placeholder).
  • Display strings (verbose_name, help_text, choices labels — must be French source per Option B) → guidelines/i18n/translation-rules.md.
  • Practice FK / multi-tenant scoping rule: which models declare a practice FK and why → guidelines/security/multi-tenant-isolation.md (placeholder).
  • Entity / ownership / consolidation domain model specifics → docs/entity-model.md (reference, not a guideline).

Sources to mine when writing this

  • apps/core/models.pyTimeStampedModel, AuditModel, SoftDeleteModel definitions and intended usage. Read class docstrings.
  • Models in well-curated apps: apps/entities/models.py, apps/dentists/models.py, apps/practices/models.py (this last one has 99 model strings and is the test bed for many conventions).
  • apps/register/models.py — recent comprehensive rewrite (BaseDocument + per-habitat concretes per roadmap/done/captable-improvements.md).

Starter hard rules to investigate

  1. Inherit from TimeStampedModel (created_at/updated_at) by default. Add AuditModel (created_by/updated_by) when audit trail matters. Add SoftDeleteModel only when records have legal/regulatory retention requirements.
  2. Choice constants are uppercase identifiers: STATUS_ACTIVE = 'active' (English keys, French labels via _('Actif') per i18n rule).
  3. Field names are English snake_case: first_name, is_active, birth_date. Display strings (verbose_name) are French.
  4. __str__ returns a French user-friendly identifier (per i18n rule); not the technical PK.
  5. Meta.ordering is explicit for any model that appears in lists. Default to a stable, sensible order.

Decision points to settle

  1. Soft-delete vs hard-delete: which models warrant SoftDelete? Patient (legal), Procedure (legal), Dentist (probably hard-delete with end_date), …?
  2. blank=True, null=True pair: official Django convention is blank=True for forms + null=True only for non-string fields. The codebase may have drifted; settle.
  3. Custom managers vs class methods: when does a model deserve a manager? (e.g., Patient.objects.active() vs Patient.objects.filter(is_active=True).)
  4. Model property vs computed field vs annotated: where does business-derived data live? Several apps have all three patterns.

Known deviations to look for during writing

  • Models without TimeStampedModel inheritance.
  • Choice tuples without constants (raw strings inline in choices=[('active', _('Actif'))]).
  • __str__ returning English / technical text (would have been caught by the i18n convergence sweep — verify).

If found, file as roadmap/backlog/backend-models-drift-2026-MM.md.