django/django
Debugging
Tactics for pinpointing failures in the framework itself.
The technical 500 page
When DEBUG = True, Django renders a detailed traceback for any unhandled exception. The page is generated by django/views/debug.py. It includes:
- The full Python traceback with source context for each frame.
- The local variables in each frame (truncated for safety).
- The request
META, GET, POST, COOKIES, FILES dicts. - The active settings (with sensitive values redacted by
SafeExceptionReporterFilter). - The full template engine context if the exception came from a template.
This page is not safe in production — it leaks settings, environment, and request state. Set DEBUG = False and configure ALLOWED_HOSTS for production.
Reading tracebacks
Django tracebacks tend to be long because almost everything goes through middleware → handler → resolver → view → ORM → backend. A few rules of thumb:
- The frame with your code in it is usually 4-6 frames from the top. Above that is middleware unwrapping; below is the framework calling into your code.
- If the traceback includes
django/db/models/sql/, the failure is in query construction, not in your model. Check what filter/annotate chain produced the call. - If it includes
django/db/backends/<engine>/, the failure originated in the database driver. The error message afterpsycopg.errors.<...>:orsqlite3.<...>:is often the most informative line. - If you see
asgiref.sync.async_to_sync, the failure crossed the sync/async boundary. The "real" frame is below the bridge.
pdb / breakpoints
breakpoint() works fine inside views, management commands, and tests. For tests:
python runtests.py queries -v 2 --debug-sql--debug-sql prints the SQL executed by failed tests; useful when an ORM-heavy test fails opaquely.
To drop into pdb on the first failure:
python runtests.py --pdbThe runserver autoreloader
django/utils/autoreload.py watches the source tree and restarts the dev server on file changes. When debugging issues with the reloader itself:
- Set
DJANGO_AUTORELOAD_VERBOSE=1for verbose logging (not a documented env var, but used internally for development). - The reloader runs in a separate process. Breakpoints in
autoreload.pyonly trigger in that process. - The reloader uses
pyinotifyon Linux when available, falling back to a stat-poll loop. The polling fallback is much slower with large source trees. - If the reloader misses changes, check that the file is on a watched path. Symlinked source roots can be skipped.
Logging
Django configures logging via django/utils/log.py and django/conf/global_settings.py (see LOGGING and LOGGING_CONFIG). The default config:
- Logs
django.requesterrors atERRORlevel to the console inDEBUG = True. - Logs
django.security.*events. - Logs
django.db.backendsSQL atDEBUGlevel (only emitted whenDEBUG = Trueand the level is unmuted).
To trace SQL during development, enable the SQL logger:
LOGGING = {
"version": 1,
"handlers": {"console": {"class": "logging.StreamHandler"}},
"loggers": {
"django.db.backends": {"handlers": ["console"], "level": "DEBUG"},
},
}Common errors and where to look
| Symptom | Likely culprit | Where in the source |
|---|---|---|
ImproperlyConfigured: settings.X |
Missing/wrong setting; usually called from django.setup() or first model import. |
django/conf/__init__.py |
AppRegistryNotReady |
Code touching models before django.setup() ran. |
django/apps/registry.py |
OperationalError: no such table |
Missing migration. | django/db/migrations/executor.py |
SuspiciousOperation: Invalid HTTP_HOST |
Request Host header not in ALLOWED_HOSTS. |
django/http/request.py |
CSRF verification failed |
Missing/expired CSRF token, or Referer mismatch with HTTPS. |
django/middleware/csrf.py |
TemplateSyntaxError |
Bad template; the message includes the template path and line. | django/template/base.py |
FieldError |
ORM filter referencing a non-existent field or relationship. | django/db/models/sql/query.py |
IntegrityError |
DB constraint violation; the wrapped DB exception has the real message. | django/db/utils.py |
RuntimeError: SynchronousOnlyOperation |
Sync ORM call from inside an async view without sync_to_async. |
django/utils/asyncio.py |
Async debugging
When an issue only manifests under ASGI:
- Reproduce with the ASGI handler in a test (
django.test.client.AsyncClient). - Check whether the failure is in the bridge or in a real async path. The bridge appears in tracebacks as
asgiref.sync.async_to_sync. - The
async_unsafedecorator (indjango/utils/asyncio.py) raises if a sync-only function is called from an async context. If you see this error, follow the call chain back to a view or middleware that should have used the async API.
Running just one failing test in a tight loop
cd tests
python runtests.py path.to.failing.test --keepdb -v 2--keepdb keeps the test database between runs so you don't pay setup cost. -v 2 prints each test name. If a test is non-deterministic, prefix with --shuffle <seed> or wrap it in a shell loop.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.