python
25 lines · 7 steps
Attaching per-request context in Django
A Django middleware that stamps each request with an ID, timing, tenant, and feature flags, then echoes them back on the response.
Explained by
highlit
1import time
2import uuid
3
4from django.utils.deprecation import MiddlewareMixin
5
6
7class RequestContextMiddleware(MiddlewareMixin):
8 def process_request(self, request):
9 request.request_id = request.headers.get("X-Request-ID") or uuid.uuid4().hex
10 request.started_at = time.monotonic()
11
12 api_key = request.headers.get("Authorization", "").removeprefix("Bearer ").strip()
13 request.api_client = ApiClient.objects.filter(
14 key=api_key, is_active=True
15 ).select_related("organization").first()
16
17 request.tenant = request.api_client.organization if request.api_client else None
18 request.feature_flags = FeatureFlag.flags_for(request.tenant)
19
20 def process_response(self, request, response):
21 response["X-Request-ID"] = getattr(request, "request_id", "")
22 if hasattr(request, "started_at"):
23 elapsed_ms = (time.monotonic() - request.started_at) * 1000
24 response["X-Response-Time-ms"] = f"{elapsed_ms:.1f}"
25 return response
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Middleware is the natural place to resolve cross-cutting context once so every view can rely on it.
- 2Reusing an incoming request ID or minting a new one gives you end-to-end request tracing for free.
- 3process_request and process_response bracket a request, letting you measure and annotate the full round trip.
Related explainers
python
from fastapi import FastAPI, WebSocket, WebSocketDisconnect app = FastAPI()
Building a WebSocket chat with FastAPI
websockets
broadcast
connection-management
Intermediate
9 steps
python
import random from typing import Iterator, List
How reservoir sampling picks k items
reservoir-sampling
streaming
randomness
Intermediate
5 steps
python
import secrets from django.contrib.auth import authenticate, login from django.core.cache import cache
Two-factor login with OTP in Django
two-factor-auth
one-time-passwords
caching
Intermediate
9 steps
typescript
import { Injectable, Scope, Inject, NotFoundException } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { Request } from 'express'; import { DataSource } from 'typeorm';
Per-tenant database connections in NestJS
multi-tenancy
connection-pooling
dependency-injection
Advanced
8 steps
go
package middleware import ( "net/http"
Per-plan export limits in Gin middleware
middleware
rate-limiting
authorization
Intermediate
7 steps
python
import re from functools import total_ordering from typing import Optional
Parsing and comparing semantic versions
regex
operator-overloading
sorting
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/attaching-per-request-context-in-django-explained-python-011b/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.