Skip to content

Django Debug Tools

Debugging is normal work in Django projects. Good developers are not people who avoid bugs. They are people who can find root causes quickly and fix them safely.

Keep your process simple and repeatable:

  • Reproduce the issue clearly.
  • Read the full traceback.
  • Locate the exact file and line.
  • Understand the root cause.
  • Apply a small fix.
  • Re-test the same flow.

Important rule: fix the cause, not the symptom.

Use these tools together:

  • Django traceback in terminal or browser error page.
  • Temporary print checks for quick local inspection.
  • Breakpoints with VS Code debugger.
  • Django shell for ORM and data checks.
  • Application logs for request-level context.

Each tool answers a different question, so combining them saves time.

When you get an exception, read from the bottom first. The last lines usually show:

  • Exception type (for example, AttributeError, KeyError, DoesNotExist).
  • Message explaining what failed.
  • The line where the error happened.

Then move upward to understand the call chain. Do not start changing code before you understand this chain.

Use shell when you need to verify model data or ORM behavior without clicking through UI pages.

Terminal window
uv run python manage.py shell

Example:

from core.models import Product
Product.objects.count()
Product.objects.first()

Use shell for:

  • Data inspection.
  • ORM query testing.
  • Small logic experiments.

print() is okay for very quick local checks, but logs are better for teams and production.

Minimal logging example in settings.py:

LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"handlers": {
"console": {
"class": "logging.StreamHandler",
},
},
"root": {
"handlers": ["console"],
"level": "INFO",
},
"loggers": {
"django.request": {
"handlers": ["console"],
"level": "ERROR",
"propagate": False,
},
},
}

Production notes:

  • Never log passwords, tokens, or private user data.
  • Keep log levels clean (DEBUG, INFO, WARNING, ERROR).
  • Add request IDs if your project handles high traffic.

Django Debug Toolbar gives a live debug panel in development pages. It is very useful for performance and ORM debugging.

You can inspect:

  • SQL queries per request.
  • Query execution time.
  • Template rendering details.
  • Request headers and settings.
  • Cache and middleware behavior.
Terminal window
uv add django-debug-toolbar
INSTALLED_APPS = [
# other apps...
]
if ENVIRONMENT != PRODUCTION:
INSTALLED_APPS += [
# ...
"debug_toolbar",
]
MIDDLEWARE = [
# other middleware...
]
if ENVIRONMENT != PRODUCTION:
MIDDLEWARE += [
# ...
"debug_toolbar.middleware.DebugToolbarMiddleware",
]
INTERNAL_IPS = [
"127.0.0.1",
]
from django.conf import settings
from django.urls import include, path
urlpatterns = [
# your URLs...
]
if settings.ENVIRONMENT != settings.PRODUCTION:
urlpatterns += [
path("__debug__/", include("debug_toolbar.urls")),
]
  • Use Debug Toolbar only in development.
  • Keep it behind settings.DEBUG checks.
  • Never expose __debug__/ endpoints in production.

Interview-ready statement:

“I use Django Debug Toolbar to identify slow ORM queries and prevent N+1 problems before release.”

VS Code debugging helps when issues are hard to trace with logs alone. Breakpoints let you pause execution and inspect variables in real time.

  • VS Code Python extension installed.
  • Django project opened at root (where manage.py exists).
{
"version": "0.2.0",
"configurations": [
{
"name": "Django: Runserver",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": ["runserver"],
"django": true,
"justMyCode": true,
"console": "integratedTerminal",
"env": {
"DJANGO_SETTINGS_MODULE": "myproject.settings"
}
}
]
}

Replace myproject.settings with your actual settings module.

{
"python.testing.pytestEnabled": true,
"python.testing.unittestEnabled": false,
"python.analysis.typeCheckingMode": "basic"
}
  • Put a breakpoint in a view, serializer, or service.
  • Start Django: Runserver from Run and Debug.
  • Trigger the endpoint in browser or API client.
  • Inspect variables, step into function calls, and validate assumptions.

If the breakpoint is not hit:

  • Confirm you started with the Django debug config, not plain Python.
  • Check that the request reaches the same file and function.
  • Restart debug session after code or config changes.