django
✓Verified·Scanned 2/18/2026
Avoid common Django mistakes — QuerySet evaluation, N+1 queries, migration conflicts, and ORM traps.
from clawhub.ai·v2539ce1·2.7 KB·0 installs
Scanned from 1.0.0 at 2539ce1 · Transparency log ↗
$ vett add clawhub.ai/ivangdavila/django
QuerySet Evaluation
- QuerySets are lazy — no DB hit until iteration, slicing, or bool
- Iterating twice hits DB twice — convert to list if reusing:
list(queryset) exists()faster thanbool(queryset)— doesn't fetch all rowscount()vslen()— count() uses SQL COUNT, len() fetches all
N+1 Queries
select_relatedfor ForeignKey/OneToOne — single JOIN queryprefetch_relatedfor ManyToMany/reverse FK — separate query, cached- Access related object in loop without prefetch = N+1 — check with django-debug-toolbar
Prefetchobject for custom querysets — filter or annotate prefetched data
ORM Gotchas
update()doesn't callsave()— no signals, no auto_nowF()for database-level operations —F('count') + 1avoids race conditionsexclude(field=None)excludes NULL — may not be what you wantdistinct()required aftervalues()in some cases — duplicate rows otherwise
Migrations
makemigrationson model change — not automatic- Migration conflicts: rename to avoid collision —
git mergecreates duplicates --mergeto combine conflicting migrations — or rebasesquashmigrationsto consolidate — but keep unsquashed until fully deployed- Fake migration if table exists —
migrate --fake appname 0001
Settings Gotchas
DEBUG=FalserequiresALLOWED_HOSTS— crashes without itSECRET_KEYmust be secret in production — env var, not in repo- Static files need
collectstaticin production — DEBUG=True serves them differently STATIC_ROOTvsSTATICFILES_DIRS— ROOT is destination, DIRS is sources
CSRF Protection
- Forms need
{% csrf_token %}— or 403 on POST - AJAX needs
X-CSRFTokenheader — get token from cookie @csrf_exemptis security risk — use only for webhooks with other auth
Testing
TestCasewraps in transaction — faster, but can't test transaction behaviorTransactionTestCaseactually commits — slower, needed for testing transactionsClientfor views,RequestFactoryfor middleware/views directlyoverride_settingsdecorator — test with different settings
Common Mistakes
get()raisesDoesNotExistorMultipleObjectsReturned— usefilter().first()for safeauto_nowcan't be overridden — usedefault=timezone.nowif need to set manually- Circular imports in models — use string reference:
ForeignKey('app.Model') related_nameconflicts — set unique or userelated_name='+'to disable