Skip to content

Manuals — Views

Overview

The views layer exposes the manuals app through REST API endpoints.

It is responsible for:

  • request parsing
  • authentication and permission enforcement
  • queryset construction
  • serializer selection
  • response construction
  • light orchestration (calling services)

It is not responsible for:

  • business logic
  • nested content synchronization
  • media cleanup workflows
  • PDF rendering internals

Those responsibilities belong to the service layer.


View structure

The views are split into modules for clarity:

  • views/taxonomy.py
  • views/manuals.py
  • views/chapters.py
  • views/callouts.py
  • views/media.py
  • views/downloads.py

This prevents one large monolithic views.py.


High-level flow

flowchart TD

Request --> Auth
Auth --> HasOrg
HasOrg --> View
View --> Serializer
Serializer --> Service
Service --> Serializer
Serializer --> Response

Shared behavior

Org scoping

All views use:

  • IsAuthenticated
  • HasCurrentOrg

Helper:

  • _org(request) extracts the active org

All querysets must be filtered by org through:

  • manual
  • chapter → manual
  • section → chapter → manual
  • step_group → chapter → manual
  • step → step_group → chapter → manual

Parser configuration

Manual-related endpoints support:

  • JSON
  • multipart/form-data
  • file uploads

Used parsers:

  • JSONParser
  • MultiPartParser
  • FormParser

Taxonomy views

CategoryViewSet

Responsibilities:

  • CRUD for categories
  • org-scoped filtering

Key behavior:

  • queryset filtered by current org
  • org automatically assigned on create

TopicViewSet

Responsibilities:

  • CRUD for topics
  • org-scoped filtering

Key behavior:

  • identical structure to CategoryViewSet
  • includes color metadata

Manual views

ManualViewSet

Main entry point for manuals.


Responsibilities

  • list manuals
  • retrieve manual detail
  • create/update manuals
  • nested content handling via serializer + services
  • filtering, search, ordering
  • cover upload/remove
  • PDF export

Query optimization

ManualViewSet dynamically adjusts queryset based on:

  • action (list vs retrieve)
  • embed query parameter

Embed parameter

Example:

  • ?embed=chapters,items

Controls whether deep relationships are prefetched.


Query strategy

flowchart TD

Callout --> Manual
Callout --> Chapter
Callout --> Section
Callout --> StepGroup
Callout --> Step

Manual --> Org
Chapter --> Org
Section --> Org
StepGroup --> Org
Step --> Org
Ensures only callouts within the current org are accessible.


Media views

ManualMediaViewSet

Responsibilities:

  • upload media
  • list media
  • delete media
  • enforce org safety
  • trigger cleanup

Create flow

flowchart TD

A[Upload request] --> B[Validate file]
B --> C[Validate parent shape]
C --> D[Check parent belongs to org]
D --> E[Create ManualMedia]
E --> F[Return serialized media]

Delete flow

flowchart TD

A[Delete media] --> B[Load media]
B --> C[Call cleanup_after_media_delete]
C --> D[Remove inline references]
D --> E[Return 204]

Key responsibilities

  • enforce parent ownership via service
  • prevent cross-org attachment
  • trigger section/step cleanup after deletion

Download views

ManualCoverDownloadView

Responsibilities:

  • serve manual cover image

Behavior:

  • validates org ownership
  • supports:
    • S3 signed redirect
    • local file streaming

ManualMediaDownloadView

Responsibilities:

  • serve media file

Behavior:

  • validates org ownership
  • supports:
    • S3 redirect
    • local streaming

⸻

Download flow

flowchart TD

Request --> ValidateOrg
ValidateOrg --> FindFile
FindFile -->|S3| Redirect
FindFile -->|Local| StreamFile

Filtering, search, ordering

Filtering

ManualViewSet supports:

  • category
  • topic
  • is_public_external

  • title
  • description

Ordering

  • published_at
  • title
  • order

Permissions

All views use layered permissions:

  • IsAuthenticated
  • HasCurrentOrg

This ensures:

  1. user is authenticated
  2. org context is resolved
  3. data is scoped to org

Responsibilities by layer

Views own

  • request parsing
  • permission checks
  • queryset filtering
  • serializer selection
  • response formatting
  • light orchestration

Services own

  • nested content synchronization
  • chapter/item orchestration
  • media cleanup
  • PDF generation

Serializers own

  • payload validation
  • response shaping

Models own

  • data integrity
  • constraints
  • relationships

Design principles

Thin views

Views should remain small and readable.

They should:

  • delegate logic
  • not implement workflows

Explicit endpoints

Custom actions are used for:

  • cover management
  • PDF export
  • file downloads

This keeps API behavior explicit.


Org-first filtering

All data access is scoped to org.

No endpoint should expose cross-org data.


Query efficiency

Deep manual responses are optimized via:

  • select_related
  • prefetch_related
  • conditional embedding

Best practices

  • keep views thin and declarative
  • always filter by org
  • avoid embedding business logic in views
  • use services for orchestration
  • use serializers for validation only
  • optimize queries when returning nested data

Future extensions

Possible improvements:

  • dedicated public/manual endpoints for external access
  • caching layer for manual detail responses
  • async PDF generation for large manuals
  • versioning support for manuals
  • granular permissions (read vs edit vs publish)
  • bulk media upload endpoints

Summary

The views layer exposes the manuals system through a clean REST interface.

It provides:

  • taxonomy endpoints
  • manual management
  • chapter management
  • callout management
  • media upload and cleanup
  • file downloads
  • PDF export

It is designed to be:

  • thin
  • org-safe
  • optimized for nested reads
  • aligned with the service layer

The key idea:

views orchestrate requests and responses; services perform the actual work.