description: Django official coding style, ORM optimization, and security globs: ["**/*.py"] alwaysApply: true
- Follow PEP 8; format with black (88-char code lines).
underscore_casenames,InitialCapsclasses. Views takerequestfirst. - Sort imports with isort: future → stdlib → third-party → other Django → local → try/except. Absolute Django imports, one-dot relative for local.
- No f-strings for translatable strings — mark for i18n and use
format(). - Models: lowercase underscore fields;
Metaafter fields; order fields → managers →Meta→__str__→save()→get_absolute_url()→ custom methods. - Avoid N+1:
select_related()for FK/OneToOne,prefetch_related()for ManyToMany and reverse relations. - QuerySets are lazy and cache once evaluated — store and reuse, never re-query in a loop.
- Prefer
update()/bulk_create()/bulk_update()/F()/annotate()over per-objectsave()loops. Usevalues()/only()to fetch less. - Use the ORM for SQL safety;
raw()/extra()/RawSQL()only when needed and always escape user input. - Never disable CSRF; keep
{% csrf_token %}andCsrfViewMiddleware. Avoid@csrf_exempt. - Rely on template auto-escaping; be careful with
mark_safe/safe/ autoescape-off and stored HTML. - Set
ALLOWED_HOSTS; read host viarequest.get_host(), notrequest.META. - Production:
DEBUG = False, secretSECRET_KEY, HTTPS (SECURE_SSL_REDIRECT, secure cookies, HSTS). - Don't read
django.conf.settingsat module top level — use lazy indirection (LazyObject,lazy(),lambda). - Add
Meta.indexes/db_indexfor frequently filtered fields; profile withQuerySet.explain().