Django cookbook · Advanced
Call external APIs concurrently in async views
A view calls three slow services one after another, so the response takes the sum of their times.
Approach
Write the view as async def, call services concurrently with asyncio.gather on a shared httpx.AsyncClient
with timeouts, and use the ORM's async methods (aget, acount, async for). Run under an ASGI server.
Solution
import asyncio
import httpx
from django.http import JsonResponse
from shop.models import Product
client = httpx.AsyncClient(timeout=httpx.Timeout(2.0, connect=1.0))
async def fetch_json(url: str) -> dict | None:
try:
response = await client.get(url)
response.raise_for_status()
return response.json()
except httpx.HTTPError:
return None # degrade gracefully
async def product_overview(request, product_id: int):
product = await Product.objects.aget(id=product_id)
stock, reviews, shipping = await asyncio.gather(
fetch_json(f"https://stock.internal/items/{product.sku}"),
fetch_json(f"https://reviews.internal/products/{product.id}"),
fetch_json(f"https://shipping.internal/estimate?sku={product.sku}"),
)
return JsonResponse({
"name": product.name,
"stock": stock and stock["available"],
"rating": reviews and reviews["average"],
"ships_in_days": shipping and shipping["days"],
})
Pitfalls
- Calling sync code (sync ORM methods,
requests) inside async views, blocking the event loop. - Async views under WSGI, where they run in a thread per request and gain nothing.
- No timeouts on outbound calls.
Variations
- Wrap unavoidable sync code with
asgiref.sync.sync_to_async(thread_sensitive=True). - Cache the slow services' responses briefly to protect them under load.
Further reading: Asynchronous support
Reference: https://docs.djangoproject.com/en/6.0/topics/async/
More Django recipes
- Add a required column without downtime
- Add full-text search with PostgreSQL
- Add health checks and structured logging
- Avoid N+1 queries with select_related and prefetch_related
- Cache expensive queries and invalidate on change
- Configure settings from environment variables
- Enforce rules with database constraints
- Harden security settings, including a Content Security Policy