Django User Guide
This guide covers how to use ZooCache with Django effectively.
Table of Contents
- Installation
- Quick Start
- Core Concepts
- Advanced Features
- Configuration
- Best Practices
- Troubleshooting
Installation
To use the Django ORM adapter, install ZooCache with the django extra:
Using uv (recommended):
Using pip:
Quick Start
1. Add ZooCacheManager to your Models
To enable caching for a model, add ZooCacheManager as a manager. It's recommended to keep the default objects manager for non-cached queries.
from django.db import models
from zoocache.contrib.django import ZooCacheManager
class Product(models.Model):
name = models.CharField(max_length=100)
category = models.CharField(max_length=50)
objects = models.Manager() # Standard manager
cached = ZooCacheManager(ttl=300) # ZooCache manager
2. Querying
Use the cached manager exactly like you would use standard Django managers:
# Hits the database and populates the cache
products = Product.cached.filter(category="electronics")
# Subsequent calls with the same filters hit the cache
products = Product.cached.filter(category="electronics")
Core Concepts
Automatic Invalidation
ZooCache automatically invalidates cached results for a model whenever an instance is saved or deleted.
# Cached query
Product.cached.all()
# Saving any instance invalidates ALL cached queries for Product
p = Product.objects.get(id=1)
p.name = "New Name"
p.save()
Transaction Support
ZooCache is transaction-aware. Invalidation is deferred until the current database transaction is successfully committed.
from django.db import transaction
with transaction.atomic():
product.save()
# Cache is still valid here (pending commit)
# Cache is invalidated ONLY after this point
Advanced Features
Dependency Detection (JOINs)
When you perform a query that involves JOINs, ZooCache automatically detects the related models and registers them as dependencies.
# This query depends on BOTH Book and Author models
books = Book.cached.filter(author__name="Isaac Asimov")
# Saving an Author will invalidate this Book query!
author.save()
Query Optimizations
ZooCache works seamlessly with select_related and prefetch_related.
# Related objects are cached alongside the main entity
books = Book.cached.select_related("author").all()
for book in books:
print(book.author.name) # No database hit!
Configuration
Manager Parameters
| Parameter | Type | Description |
|---|---|---|
ttl |
int |
Override the default TTL for this manager's queries. |
prefix |
str |
Optional namespace prefix for cache keys. |
ensure_objects_manager |
bool |
If True (default), automatically injects objects = models.Manager() if not defined. |
[!TIP] By default, ZooCache ensures that an
objectsmanager is available. This prevents the common Django issue where adding a custom manager removes the defaultobjectsmanager.
# 'objects' is automatically available even if not defined
cached = ZooCacheManager(ttl=60, prefix="fast_cache")
Global Configuration
The preferred way to configure ZooCache in Django is by adding a ZOOCACHE dictionary to your settings.py. ZooCache will automatically detect these settings.
# settings.py
ZOOCACHE = {
"storage_url": "redis://localhost:6379",
"bus_url": "redis://localhost:6379",
"default_ttl": 3600,
}
Alternative: Manual Configuration
If you need more control or want to configure ZooCache programmatically, you can still use the AppConfig.ready() pattern:
# myapp/apps.py
from django.apps import AppConfig
import zoocache
class MyAppConfig(AppConfig):
name = 'myapp'
def ready(self):
# This will only run if ZOOCACHE is not defined in settings.py
zoocache.configure(
storage_url="redis://localhost:6379",
default_ttl=3600
)
Best Practices
- Keep
objectsas Default: Always keep a standardmodels.Manager()to avoid accidental caching in administrative or write-heavy tasks. - Monitor Model Write Frequency: Models that are updated frequently (e.g.,
Session,Log) will have a low cache hit rate because every save invalidates the whole model's cache. - Use for Read-Heavy Views: Identify your most expensive read queries and use
.cachedthere for the biggest performance gains.
Troubleshooting
Stale Data after Bulk Operations
Django's .update(), .bulk_create(), and .bulk_update() do not trigger signals. Use manual invalidation if needed:
from zoocache import invalidate
# Invalidate all Product queries
invalidate("django.model:myapp.product")
Large Cache Size
If your cache grows too large, ensure you have configured auto_prune_secs in your global ZooCache configuration.