Open-Source Wikis

/

Django

/

How to contribute

/

Debugging

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 after psycopg.errors.<...>: or sqlite3.<...>: 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 --pdb

The 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=1 for verbose logging (not a documented env var, but used internally for development).
  • The reloader runs in a separate process. Breakpoints in autoreload.py only trigger in that process.
  • The reloader uses pyinotify on 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.request errors at ERROR level to the console in DEBUG = True.
  • Logs django.security.* events.
  • Logs django.db.backends SQL at DEBUG level (only emitted when DEBUG = True and 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:

  1. Reproduce with the ASGI handler in a test (django.test.client.AsyncClient).
  2. 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.
  3. The async_unsafe decorator (in django/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.

Debugging – Django wiki | Factory