Aller au contenu

Views

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 class-based views: which mixins to use for which view type, HTMX response handling, permission/access patterns, where business logic lives (services vs views), naming.

Out of scope (cross-refs)

  • Search / sort / filter mixin contract (SortableFilterableListMixin, scope filters, URL/cookie state) → guidelines/ui/search-sort-filter.md. This file covers the broader CBV conventions; sort/filter is documented there.
  • Form construction (Form / ModelForm classes, clean_*, validation placement) → guidelines/backend/forms.md (placeholder).
  • Template rendering (list / detail / form layouts) → guidelines/ui/lists.md, detail-pages.md, forms.md.
  • Queryset scoping for multi-tenancyguidelines/security/multi-tenant-isolation.md (placeholder). This file references the mixin; multi-tenant.md owns the rule.
  • Permission decorators / mixins (LoginRequiredMixin, FeatureRequiredMixin, custom access checks) → guidelines/security/auth-and-permissions.md (placeholder).

Sources to mine when writing this

  • apps/core/mixins.pySortableFilterableListMixin, HtmxResponseMixin, MultiPracticeFilterMixin, PeriodFilterMixin, FeatureRequiredMixin. Read all class docstrings.
  • Reference views from apps with the cleanest pattern: apps/practices/views.py, apps/dentists/views.py, apps/register/views.py.
  • apps/imports/views.py — recently rewritten with constants pattern + i18n fixes (commit 8a023fd); good reference for messages.*() usage.
  • apps/finance/views.py — uses FinanceFilterMixin (the known deviation tracked in roadmap/backlog/finance-filter-unify.md).
  • apps/websites/views_cms.py — DRF-style API view; out of scope but worth noting.

Starter hard rules to investigate

  1. Compose the blessed mixins: list views inherit HtmxResponseMixin + FeatureRequiredMixin + filter mixins + SortableFilterableListMixin + ListView. Mixin order matters (Django MRO).
  2. Business logic lives in apps/<app>/services/, not in views. Views are thin: parse → call service → render.
  3. HTMX responses go through HtmxResponseMixin — never hand-roll partial vs full template selection.
  4. messages.*() calls use gettext_lazy-wrapped constants for repeated messages (per guidelines/i18n/translation-rules.md IMPORT_STARTED_MSG pattern).
  5. get_context_data is for context only — no business logic, no DB queries beyond what the queryset already loads.

Decision points to settle

  1. Service-layer naming: apps/<app>/services/<name>.py files vs apps/<app>/services.py single module. Codebase has both; pick.
  2. get_queryset() vs class queryset: when to use each. Multi-tenant filtering forces get_queryset().
  3. Function-based views: are they ever acceptable? (sync sample view in apps/sync/ uses @require_POST + function — document the rule.)
  4. DRF vs Django views for apps/websites/: keep separate or write a shared base?

Known deviations to look for during writing

  • Views with transaction.atomic + business logic inline (should be in service).
  • Views overriding dispatch for permission checks instead of using a mixin.
  • List views that bypass SortableFilterableListMixin for "simplicity" (track per search-sort-filter.md Known deviations).

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