Claude
Skills
Sign in
Back

debug:django

Included with Lifetime
$97 forever

Debug Django web applications with systematic diagnostic approaches. This skill covers troubleshooting Django-specific errors including TemplateDoesNotExist, ImproperlyConfigured, IntegrityError, migration conflicts, CSRF failures, N+1 query problems, and circular imports. Includes Django Debug Toolbar setup, ORM query logging, pdb/ipdb usage, shell_plus debugging, and comprehensive logging configuration. Provides four-phase methodology for root cause analysis and regression prevention.

Backend & APIs

What this skill does


# Django Debugging Guide

## Overview

Django debugging requires understanding the framework's layered architecture: settings, URL routing, views, templates, models, and middleware. Effective debugging follows a systematic approach - reproducing the bug, isolating the problem, gathering evidence, and implementing verified fixes.

Key principles:
- **Reproduce first**: Repeat the exact steps that cause the issue
- **Isolate systematically**: Identify the exact module, function, or code path
- **Gather evidence**: Collect error messages, stack traces, logs, and database state
- **Test your fix**: Verify the solution with automated tests

## Common Error Patterns

### TemplateDoesNotExist
**Cause**: Django cannot find the specified template file.

**Investigation steps**:
1. Check template exists in the correct directory
2. Verify `TEMPLATES['DIRS']` setting includes your template directories
3. Check for typos in template path
4. Ensure app is in `INSTALLED_APPS` if using app-specific templates

```python
# Check template configuration
python manage.py shell -c "from django.conf import settings; print(settings.TEMPLATES)"

# Verify template directories exist
python manage.py shell -c "import os; from django.conf import settings; print([d for d in settings.TEMPLATES[0]['DIRS'] if os.path.exists(d)])"
```

### ImproperlyConfigured
**Cause**: Django configuration error in settings.py or environment.

**Common causes**:
- Missing or incorrect `DJANGO_SETTINGS_MODULE`
- Invalid database configuration
- Missing required settings
- Incorrect app configuration

```bash
# Check settings module
echo $DJANGO_SETTINGS_MODULE

# Validate configuration
python manage.py check

# Compare with defaults
python manage.py diffsettings
```

### IntegrityError / Database Errors
**Cause**: Database constraint violations or missing migrations.

**OperationalError (missing column/table)**:
```bash
# Check migration status
python manage.py showmigrations

# Create missing migrations
python manage.py makemigrations

# Apply migrations
python manage.py migrate

# Check SQL that would be executed
python manage.py sqlmigrate <app_name> <migration_number>
```

**IntegrityError (constraint violation)**:
```python
# Check for duplicates before insert
from django.db import IntegrityError

try:
    obj.save()
except IntegrityError as e:
    # Log the error, check constraint name
    print(f"Constraint violation: {e}")
```

### N+1 Query Problems
**Cause**: Inefficient database queries in loops.

**Detection**:
```python
# In settings.py (development only)
LOGGING = {
    'version': 1,
    'handlers': {'console': {'class': 'logging.StreamHandler'}},
    'loggers': {
        'django.db.backends': {
            'level': 'DEBUG',
            'handlers': ['console'],
        }
    }
}
```

**Solution - use select_related/prefetch_related**:
```python
# Bad: N+1 queries
for order in Order.objects.all():
    print(order.customer.name)  # Extra query per order

# Good: Single query with join
for order in Order.objects.select_related('customer'):
    print(order.customer.name)

# For many-to-many or reverse foreign keys
orders = Order.objects.prefetch_related('items')
```

### Migration Conflicts
**Cause**: Multiple developers creating migrations on same app.

```bash
# View migration graph
python manage.py showmigrations --plan

# Merge conflicting migrations
python manage.py makemigrations --merge

# Reset migrations (development only - DANGEROUS)
python manage.py migrate <app_name> zero
python manage.py makemigrations <app_name>
python manage.py migrate <app_name>
```

### CSRF Verification Failures
**Cause**: Missing CSRF token or misconfigured trusted origins.

**Checklist**:
1. Include `{% csrf_token %}` in forms
2. Check `CSRF_TRUSTED_ORIGINS` for HTTPS sites
3. Verify middleware includes `CsrfViewMiddleware`
4. For AJAX, include CSRF token in headers

```python
# settings.py - for cross-origin requests
CSRF_TRUSTED_ORIGINS = [
    'https://your-domain.com',
]
```

### Import Errors / Circular Imports
**Cause**: Circular dependencies between modules.

**Detection**:
```bash
# Check for import errors
python -c "import your_app"

# Verbose import tracing
python -v -c "import your_app" 2>&1 | grep "import"
```

**Solutions**:
- Move imports inside functions (lazy import)
- Restructure modules to break cycles
- Use string references for model relationships

```python
# Avoid circular import with lazy import
def my_function():
    from other_module import SomeClass  # Import inside function
    return SomeClass()

# Use string reference in ForeignKey
class Order(models.Model):
    customer = models.ForeignKey('customers.Customer', on_delete=models.CASCADE)
```

### DoesNotExist
**Cause**: Querying for an object that does not exist in the database.

```python
# Bad: Raises DoesNotExist
user = User.objects.get(id=999)

# Good: Handle missing objects
from django.shortcuts import get_object_or_404
user = get_object_or_404(User, id=999)

# Or use get_or_create
user, created = User.objects.get_or_create(
    username='john',
    defaults={'email': '[email protected]'}
)

# Or wrap in try-except
try:
    user = User.objects.get(id=999)
except User.DoesNotExist:
    user = None
```

### DisallowedHost
**Cause**: Request host not in ALLOWED_HOSTS setting.

```python
# settings.py
ALLOWED_HOSTS = [
    'localhost',
    '127.0.0.1',
    'your-domain.com',
    '.your-domain.com',  # Wildcard for subdomains
]
```

### NoReverseMatch
**Cause**: URL reverse lookup failed - URL name not found or wrong arguments.

```bash
# List all URL patterns
python manage.py show_urls  # requires django-extensions

# Or manually inspect
python manage.py shell -c "from django.urls import get_resolver; print([p.name for p in get_resolver().url_patterns])"
```

```python
# Check URL name matches exactly
from django.urls import reverse
url = reverse('app_name:view_name', args=[object_id])
url = reverse('app_name:view_name', kwargs={'pk': object_id})
```

## Debugging Tools

### Django Debug Toolbar
The most powerful visual debugging tool for Django development.

**Installation**:
```bash
pip install django-debug-toolbar
```

**Configuration**:
```python
# settings.py (development only)
INSTALLED_APPS = [
    # ...
    'debug_toolbar',
]

MIDDLEWARE = [
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    # ... other middleware
]

INTERNAL_IPS = ['127.0.0.1']

# For Docker
DEBUG_TOOLBAR_CONFIG = {
    'SHOW_TOOLBAR_CALLBACK': 'debug_toolbar.middleware.show_toolbar_with_docker',
}
```

```python
# urls.py
from debug_toolbar.toolbar import debug_toolbar_urls

urlpatterns = [
    # ... your URLs
] + debug_toolbar_urls()
```

**Key panels**:
- **SQL**: All database queries with timing and EXPLAIN
- **Templates**: Rendered templates and context variables
- **Cache**: Cache hits/misses
- **Request**: Headers, cookies, session data
- **Signals**: Django signals fired

### Python Debugger (pdb/ipdb)

```python
# Insert breakpoint in code
breakpoint()  # Python 3.7+ (uses PYTHONBREAKPOINT env var)

# Or explicitly
import pdb; pdb.set_trace()

# For better experience
import ipdb; ipdb.set_trace()
```

**Common pdb commands**:
- `n` (next): Execute next line
- `s` (step): Step into function
- `c` (continue): Continue execution
- `p variable`: Print variable value
- `pp variable`: Pretty print
- `l` (list): Show current code
- `w` (where): Show stack trace
- `q` (quit): Exit debugger

### django-extensions shell_plus

```bash
pip install django-extensions

# Add to INSTALLED_APPS
INSTALLED_APPS = ['django_extensions', ...]

# Use enhanced shell with auto-imports
python manage.py shell_plus

# With IPython
python manage.py shell_plus --ipython

# Print SQL queries
python manage.py shell_plus --print-sql
```

### Logging Configuration

```python
# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '{levelname} {asctime} {module} {message}',
 

Related in Backend & APIs