dj-architecture
Implement a Django Feature
You are implementing a feature in an opinionated, fully type-safe Django project managed with uv. Every convention below is mandatory. Do not deviate.
Why this architecture exists: Django's ORM is powerful but hard to type — querysets, model instances, related managers, and F()/Q() expressions don't play well with static type checkers. This project solves that by pushing all ORM usage into repositories that return Pydantic DTOs. Services receive repos via constructor injection and contain pure business logic with zero ORM imports. Views are thin dispatchers. The result: everything from the repository boundary outward is fully typed, IDE-friendly, and testable in isolation.
Tooling: uv is the package manager. All commands use uv run. Never use pip, poetry, or raw python — always uv run python, uv run pytest, etc. To add a dependency: uv add <package>.
BEFORE WRITING CODE
Gather current project state by reading:
src/project/ids.py— existing ID prefixes (must be unique)src/project/services.py— registered repos/servicessrc/project/settings.py—INSTALLED_APPSsrc/project/api/__init__.py—NinjaAPI(), mounted resource routers, exception handlerssrc/project/api/<resource>/— existing per-resource route packagessrc/project/types.py—AuthedRequestand other shared request typesARCHITECTURE.mdif present — full pattern reference
More from dvf/opinionated-django
services
Structure Django business logic as plain services that receive their dependencies via constructor injection, and wire them through an svcs registry so they can be resolved anywhere — views, Celery tasks, management commands, tests. Use when adding a new service, refactoring fat views or model methods into a service, wiring a service into the registry, or explaining where business logic should live in this project.
11dj-lint
Run linting, formatting, and static type checks on a Django project using ruff and pyrefly, and fix any issues found. Use after making code changes, before committing, or whenever the user asks to lint, format, or type-check the codebase.
11architecture
Implement a Django feature following the opinionated architecture — prefixed ULID IDs, repository pattern, Pydantic DTOs, svcs service locator, project-scoped django-ninja API, Celery reliable signals, and layered tests. Use when the user asks to add a new entity, endpoint, app, or business logic in a Django project that follows these conventions.
11dj-pytest
Set up and write pytest tests for an op-django project — pytest-django configuration, Celery eager mode for reliable-signal tests, freezegun for time-sensitive logic, shared conftest fixtures for DTOs and svcs overrides, and the three-layer test convention (repository against a real DB, service against mocked repos, API through HTTP). Use when adding tests to a new project, writing tests for a new feature, setting up test infrastructure, or explaining how tests should be organized.
11lint
Run linting, formatting, and static type checks on a Django project using ruff and pyrefly, and fix any issues found. Use after making code changes, before committing, or whenever the user asks to lint, format, or type-check the codebase.
10pytest
Set up and write pytest tests for an op-django project — pytest-django configuration, Celery eager mode for reliable-signal tests, freezegun for time-sensitive logic, shared conftest fixtures for DTOs and svcs overrides, and the three-layer test convention (repository against a real DB, service against mocked repos, API through HTTP). Use when adding tests to a new project, writing tests for a new feature, setting up test infrastructure, or explaining how tests should be organized.
10