Django Easy Cache

Intelligent caching decorators for Django with time-based invalidation, cron-based scheduling, and comprehensive analytics. Transform your Django application’s caching from manual, error-prone boilerplate into elegant, maintainable decorators.

License PyPI version Python versions Django versions Coverage Tests Documentation Status

✨ Features

  • πŸ•’ Time-Based Invalidation: Automatically invalidate caches at specific times with timezone support

  • ⏰ Cron-Based Scheduling: Flexible cache invalidation using cron expressions

  • πŸ“Š Database Analytics: Comprehensive cache performance tracking and monitoring

  • πŸ”’ Cache Key Validation: Built-in cache key validation and length limits

  • πŸŽ›οΈ Django Admin: Administrative interface for cache entries and event history

  • πŸ“š Type Hints: Complete type annotations for better IDE support

  • πŸ—οΈ Modular Architecture: Separated concerns for better maintainability

  • πŸ›‘οΈ Robust Error Handling: Graceful degradation with specific exception handling

πŸš€ Quick Start

Installation

pip install django-easy-cache

Basic Setup

Add to your INSTALLED_APPS:

INSTALLED_APPS = [
    # ... your apps
    "easy_cache",
]

Run migrations:

python manage.py migrate

Your First Easy Cache

Replace this caching boilerplate:

# BEFORE: 20+ lines of manual cache management
def get_data(location_id: int):
    now = timezone.now()
    cache_key = f"data_{location_id}_{now.date()}_{now.hour >= 13}"

    cached_result = cache.get(cache_key)
    if cached_result is not None:
        return cached_result

    result = expensive_data_calculation(location_id)

    # Calculate timeout until 13:00 next day
    next_invalidation = now.replace(hour=13, minute=0, second=0, microsecond=0)
    if now.hour >= 13:
        next_invalidation += timedelta(days=1)

    timeout = int((next_invalidation - now).total_seconds())
    cache.set(cache_key, result, timeout)

    return result

With this:

# AFTER: 3 lines with Easy Cache
from easy_cache import easy_cache


@easy_cache.time_based(
    invalidate_at="13:00",
)
def get_data(location_id: int):
    return expensive_data_calculation(location_id)

πŸ“– API Reference

Time-Based Caching

from easy_cache import easy_cache


@easy_cache.time_based(
    invalidate_at="14:00",  # Invalidate daily at 14:00
)
def get_daily_report(date: str):
    return generate_expensive_report(date)

Cron-Based Caching

from easy_cache import easy_cache


@easy_cache.cron_based(cron_expression="*/30 * * * *")
def get_live_metrics():
    return fetch_realtime_data()

Advanced Configuration

# settings.py
easy_cache = {
    "DEFAULT_BACKEND": "default",
    "KEY_PREFIX": "easy_cache",
    # Value length for each key
    "MAX_VALUE_LENGTH": 100,
    "DEBUG_TOOLBAR_INTEGRATION": False,  # not implemented yes
    # Analytics & Monitoring
    "TRACKING": {
        "TRACK_CACHE_HITS": False,
        "TRACK_CACHE_MISSES": True,
        "TRACK_PERFORMANCE": False,
    },
    "EVENTS": {
        "EVENT_CACHE_HITS": False,
        "EVENT_CACHE_MISSES": False,
        "EVENT_CACHE_ERRORS": False,
    },
}

πŸ› οΈ Management Commands

Cache Status & Analytics

# Check cache system health
python manage.py easy_cache status

# Detailed analytics report
python manage.py easy_cache analytics --days=7 --format=table

# JSON format for automation
python manage.py easy_cache analytics --format=json

Cache Management

# Clear all cache entries and database records
python manage.py easy_cache clear --all

# Clear only cache entries and their database records
python manage.py easy_cache clear --cache-entries

# Clear only event history
python manage.py easy_cache clear --event-history

πŸŽ›οΈ Django Admin Integration

Easy Cache provides a Django Admin interface at /admin/django_easy_cache/:

  • Cache Entries: Monitor cache performance, hit rates, and access patterns

  • Event History: Analyze cache events and performance metrics

🐳 Docker Development

Quick Start with Docker

Start the development environment:

docker-compose up -d

This will start:

  • Django application with auto-reload

  • Redis cache backend

  • PostgreSQL database

  • Qdrant vector database

Docker Build Options

You can control which optional dependencies are installed during the Docker build process using build arguments:

# Build with all dependencies (default in docker-compose.yml)
docker-compose build

# Build with only core dependencies
docker build --build-arg UV_INSTALL_DEV=false --build-arg UV_INSTALL_REDIS=false --build-arg UV_INSTALL_POSTGRESQL=false -t django-easy-cache .

# Build with development dependencies only
docker build --build-arg UV_INSTALL_DEV=true --build-arg UV_INSTALL_REDIS=false --build-arg UV_INSTALL_POSTGRESQL=false -t django-easy-cache .

# Build with Redis support only
docker build --build-arg UV_INSTALL_DEV=false --build-arg UV_INSTALL_REDIS=true --build-arg UV_INSTALL_POSTGRESQL=false -t django-easy-cache .

# Build with PostgreSQL support only
docker build --build-arg UV_INSTALL_DEV=false --build-arg UV_INSTALL_REDIS=false --build-arg UV_INSTALL_POSTGRESQL=true -t django-easy-cache .

# Custom docker-compose override
```yml
services:
  dev:
    build:
      args:
        UV_INSTALL_DEV: "true"
        UV_INSTALL_REDIS: "true"
        UV_INSTALL_POSTGRESQL: "false"

Available Build Arguments

  • UV_INSTALL_DEV: Install development dependencies (default: true)

  • UV_INSTALL_REDIS: Install Redis dependencies (default: true)

  • UV_INSTALL_POSTGRESQL: Install PostgreSQL dependencies (default: true)

These can be combined as needed. For example, you can install both dev and Redis dependencies by setting both flags to true.

πŸ§ͺ Testing Support

Easy Cache includes comprehensive testing utilities:

πŸ”’ Security Features

  • Cache Key Validation: Automatic validation of cache keys for length and problematic characters

  • Length Limits: Configurable maximum key lengths (default: 250 characters)

πŸ“Š Performance Analytics

Easy Cache provides cache analytics:

# View cache performance
python manage.py easy_cache analytics

# Output:
# Cache Analytics (last 7 days)
# ----------------------------------------
# Total Entries: 42
# Average Hit Rate: 78.5%

# JSON format for automation
python manage.py easy_cache analytics --format=json

πŸ—οΈ Architecture

Core Components

  • **KeyGenerator**: Efficient cache key generation with expiration support

  • **StorageHandler**: Simple and robust cache storage operations

  • **AnalyticsTracker**: Optimized synchronous analytics tracking

  • **TimeDecorator**: Time-based caching implementation

  • **CronDecorator**: Cron-based caching implementation

  • **BaseCacheDecorator**: Refactored base class using separated components

  • **EasyCacheConfig**: Centralized configuration management

  • Analytics Models: Database tracking of cache performance

Design Patterns

  • Decorator Pattern: Clean separation of caching logic from business logic

  • Strategy Pattern: Pluggable invalidation strategies

  • Singleton Pattern: Configuration management

  • Observer Pattern: Analytics event tracking

  • Factory Pattern: Cache backend initialization

  • Composition Pattern: Separated concerns for better maintainability

  • Single Responsibility: Each component has one clear purpose

🀝 Contributing

We welcome contributions!

  1. Fork the repository

  2. Create a feature branch (git checkout -b feature/amazing-feature)

  3. Make your changes

  4. Add tests for your changes

  5. Run the test suite (pytest)

  6. Commit your changes (git commit -m 'Add amazing feature')

  7. Push to the branch (git push origin feature/amazing-feature)

  8. Open a Pull Request

πŸ› Bug Reports & Feature Requests

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

Inspired by real-world caching challenges in Django applications. Built on the solid foundation of Django’s caching framework with community-driven development and feedback.

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

0.1.0


New features

  • Time-based cache invalidation with timezone support

  • Cron-based cache invalidation with flexible scheduling

  • Database analytics and performance tracking

  • Django Admin integration for cache entries and event history

  • Management commands for cache status, analytics, and clearing

  • @easy_cache.time_based() decorator for daily invalidation at specific times

  • @easy_cache.cron_based() decorator for flexible cron-based invalidation

  • Automatic cache key generation with collision avoidance

  • Database models for cache analytics (CacheEntry, CacheEventHistory)

  • Management commands: status, analytics, clear

  • Django Admin interface at /admin/django_easy_cache/

Bug fixes

  • Fix package name configuration for Sphinx documentation

  • Resolve CI database conflicts and modernize database configuration

  • Allow CI to run pre-commit on protected branches while enforcing local branch restrictions

Technical improvements

  • Built on Django’s cache framework for backend compatibility

  • Support for Redis, Memcached, Database, and Local Memory cache backends

  • Atomic database operations for analytics tracking

  • Thread-safe cache operations

  • Comprehensive cache key validation

  • Type hints throughout the codebase

  • Modular architecture with separated concerns

  • Robust error handling with graceful degradation

  • Comprehensive test suite with pytest

  • Replace pre-commit branch restrictions with GitHub rulesets