SDKs
Python
Django

Django Integration

Capture errors and request context from Django applications.

Installation

pip install statly-observe

Setup

1. Configure Settings

Add to settings.py:

# settings.py
 
INSTALLED_APPS = [
    # ... other apps
    'statly_observe',
]
 
MIDDLEWARE = [
    'statly_observe.integrations.django.StatlyDjangoMiddleware',
    # ... other middleware
    # Put StatlyMiddleware near the top to catch all errors
]
 
# Statly configuration
STATLY_DSN = 'https://[email protected]/your-org'
STATLY_ENVIRONMENT = 'production'  # or from env
STATLY_RELEASE = '1.0.0'  # optional

2. Initialize in AppConfig

# myapp/apps.py
from django.apps import AppConfig
from statly_observe import Statly
 
class MyAppConfig(AppConfig):
    name = 'myapp'
 
    def ready(self):
        from django.conf import settings
 
        Statly.init(
            dsn=settings.STATLY_DSN,
            environment=getattr(settings, 'STATLY_ENVIRONMENT', 'development'),
            release=getattr(settings, 'STATLY_RELEASE', None),
        )

What's Captured

Request Context

For each error, the middleware captures:

  • HTTP method and absolute URL
  • Path and query string
  • Headers (sanitized)
  • POST data and JSON body (sanitized)
  • Client IP (with X-Forwarded-For support)
  • Django view name and URL name
  • Resolver match information

Automatic Sanitization

Sensitive data is filtered:

Headers:

  • authorization
  • cookie
  • x-api-key
  • x-auth-token

POST/Body fields:

  • password
  • secret
  • token
  • api_key
  • credit_card
  • ssn
  • csrfmiddlewaretoken

With Django Auth

Automatically capture authenticated users:

# The middleware automatically checks request.user
 
# If request.user.is_authenticated:
#   Sets user context with id, email, username

Or set additional user data:

# views.py
from statly_observe import Statly
 
def my_view(request):
    if request.user.is_authenticated:
        Statly.set_user(
            id=str(request.user.id),
            email=request.user.email,
            username=request.user.username,
            role=request.user.role,  # Custom field
        )
    # ...

Logging Integration

Use Django's logging with Statly:

# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'statly': {
            'level': 'ERROR',
            'class': 'statly_observe.integrations.django.StatlyDjangoHandler',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['statly'],
            'level': 'ERROR',
            'propagate': True,
        },
        'myapp': {
            'handlers': ['statly'],
            'level': 'ERROR',
            'propagate': True,
        },
    },
}

Class-Based Views

Works automatically with CBVs:

from django.views import View
from django.http import JsonResponse
from statly_observe import Statly
 
class OrderView(View):
    def post(self, request):
        try:
            order = create_order(request.POST)
            return JsonResponse({'id': order.id})
        except PaymentError as e:
            Statly.capture_exception(e, context={
                'order_total': request.POST.get('total'),
            })
            return JsonResponse({'error': 'Payment failed'}, status=400)

Django REST Framework

Works with DRF views and viewsets:

from rest_framework.views import APIView
from rest_framework.response import Response
from statly_observe import Statly
 
class UserAPIView(APIView):
    def get(self, request):
        # Errors are automatically captured
        users = User.objects.all()
        return Response({'users': list(users.values())})
 
    def post(self, request):
        try:
            user = User.objects.create(**request.data)
            return Response({'id': user.id}, status=201)
        except Exception as e:
            Statly.capture_exception(e)
            raise

Celery Tasks

Capture errors in Celery tasks:

# tasks.py
from celery import shared_task
from statly_observe import Statly
 
@shared_task
def process_order(order_id):
    try:
        order = Order.objects.get(id=order_id)
        # Process order
    except Exception as e:
        Statly.capture_exception(e, context={
            'order_id': order_id,
            'task': 'process_order',
        })
        raise

Full Example

# settings.py
import os
 
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'myapp',
    'statly_observe',
]
 
MIDDLEWARE = [
    'statly_observe.integrations.django.StatlyDjangoMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
]
 
STATLY_DSN = os.environ.get('STATLY_DSN')
STATLY_ENVIRONMENT = os.environ.get('DJANGO_ENV', 'development')
STATLY_RELEASE = os.environ.get('GIT_SHA')
# myapp/apps.py
from django.apps import AppConfig
 
class MyAppConfig(AppConfig):
    name = 'myapp'
 
    def ready(self):
        from statly_observe import Statly
        from django.conf import settings
 
        if settings.STATLY_DSN:
            Statly.init(
                dsn=settings.STATLY_DSN,
                environment=settings.STATLY_ENVIRONMENT,
                release=settings.STATLY_RELEASE,
            )