---
trigger: glob
globs: **/*.py,**/templates/**
---

# Django 5.2

- One Django app per domain area. Business logic in `services.py` functions or model methods, not in views or templates.
- Models: explicit `related_name`, `on_delete`, `Meta.ordering` only when needed, `constraints` (`UniqueConstraint`, `CheckConstraint`) instead of app-level checks. Use `db_default` for DB-side defaults.
- After model changes run `python manage.py makemigrations <app>` and review the file. Data migrations use `RunPython` with the historical model (`apps.get_model`).
- ORM performance: `select_related`/`prefetch_related` for related data, `only()`/`values()` for large reads, `bulk_create`/`update()` for batch writes, `F()` expressions for atomic updates. Avoid queries inside loops and templates.
- Class-based or function views, matching the app; protect them with `LoginRequiredMixin`/`@login_required` and permission checks.
- Forms (`ModelForm`) validate all user input; templates keep autoescape on and include `{% csrf_token %}`.
- Settings from env (django-environ or similar); `DEBUG=False` and `ALLOWED_HOSTS` in production.
- Async views only when the whole call chain is async (`aget`, `afilter`).

## Done when
`python manage.py check --deploy` (for settings changes), `makemigrations --check`, `ruff check .`, and the test suite (`pytest` or `manage.py test`) pass.
