Install & Compatibility
Where this runs
tested against v7.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.920 runs
installs and imports cleanly · install 0.0s · import 0.000s · 71.6MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 3.8s · import 0.000s · 72MB
71MB installed
● package 71MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
cached
✓ from cacheops import cached
✗ from cacheops import cached_queryset
invalidate_obj
✓ from cacheops import invalidate_obj
invalidate_model
✓ from cacheops import invalidate_model
This quickstart demonstrates how to configure django-cacheops with minimal Django settings and use its core features: caching querysets with `.cache()`, explicit model invalidation, and the `@cached_queryset` decorator for functions returning querysets. It assumes a Redis server is accessible at `redis://localhost:6379/1` or specified via the `CACHEOPS_REDIS` environment variable.
import os
import django
from django.conf import settings
from django.db import models
# Minimal Django settings for a runnable example
# In a real project, these would be in your settings.py
if not settings.configured:
settings.configure(
INSTALLED_APPS=[
'django.contrib.auth',
'django.contrib.contenttypes',
'cacheops', # Add cacheops to your installed apps
'myapp', # A dummy app for model definition
],
CACHEOPS_REDIS=os.environ.get('CACHEOPS_REDIS', 'redis://localhost:6379/1'),
# CACHEOPS_ENABLED defaults to True since v7.0
# CACHEOPS_TIMEOUT defaults to 3600 (1 hour) since v7.0
DATABASES={
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:',
}
},
USE_TZ=True,
TIME_ZONE='UTC',
)
django.setup()
# Define a simple Django model. For demonstration, we use 'myapp' as app_label.
class Post(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
app_label = 'myapp' # Required when defining models outside an actual app directory
def __str__(self):
return self.title
# Ensure the database schema is created for the model (for in-memory SQLite)
from django.db import connection
with connection.schema_editor() as schema_editor:
schema_editor.create_model(Post)
print(f"Using Redis connection string: {settings.CACHEOPS_REDIS}")
# Create some sample data
Post.objects.create(title="First Post", body="Content of the first post.")
Post.objects.create(title="Second Article", body="More content here.")
# --- Example 1: Caching a Queryset ---
print("\n--- Example 1: Caching a Queryset ---")
# The .cache() method makes the queryset result be cached.
# First call will hit the database and store the result in cache.
posts = Post.objects.filter(title__icontains='post').cache().all()
print(f"Posts (first fetch, hits DB and caches): {[p.title for p in posts]}")
# Subsequent calls with the same query parameters will hit the cache.
posts_cached = Post.objects.filter(title__icontains='post').cache().all()
print(f"Posts (second fetch, should hit cache): {[p.title for p in posts_cached]}")
# --- Example 2: Invalidating Cache ---
from cacheops import invalidate_model
print("\n--- Example 2: Invalidating Cache ---")
# Update an object (usually auto-invalidates if configured)
post_to_update = Post.objects.get(title="First Post")
post_to_update.title = "Updated First Post"
post_to_update.save()
# Explicitly invalidate all caches related to the Post model
invalidate_model(Post)
print("Post model cache explicitly invalidated.")
# Fetching again will hit the DB to get the updated data and re-cache.
updated_posts = Post.objects.filter(title__icontains='post').cache().all()
print(f"Posts after update and invalidation: {[p.title for p in updated_posts]}")
# --- Example 3: Using @cached_queryset decorator ---
from cacheops import cached_queryset
print("\n--- Example 3: Using @cached_queryset decorator ---")
@cached_queryset
def get_latest_articles(limit=1):
print(" (Fetching from DB inside get_latest_articles)")
return Post.objects.order_by('-created_at')[:limit]
# First call of the decorated function
latest1 = get_latest_articles()
print(f"Latest article (first call): {[p.title for p in latest1]}")
# Second call of the decorated function should hit the cache
latest2 = get_latest_articles()
print(f"Latest article (second call, should hit cache): {[p.title for p in latest2]}")
Upgrade
Version history
7.2latest on PyPI · released Apr 20, 2025
Audit
Dependencies
redisrequiredRedis server and client library are required for cache backend operations. Ensure a Redis server is running and accessible.