← Назад к вопросам

Как подключить кэширование в Django?

2.0 Middle🔥 111 комментариев
#Django

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Подключение кэширования в Django

Кэширование — это критический инструмент для оптимизации производительности веб-приложений. Django предоставляет гибкий фреймворк для работы с различными бэкендами кэша.

Выбор бэкенда кэша

Django поддерживает несколько бэкендов кэширования:

1. Memcached — рекомендуемый вариант для production:

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
        "LOCATION": "127.0.0.1:11211",
    }
}

2. Redis — популярный выбор для сложных сценариев:

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient"
        }
    }
}

3. Локальное хранилище (development):

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
        "LOCATION": "unique-snowflake",
    }
}

Способы кэширования

Кэширование представлений (View-level):

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)  # 15 минут
def my_view(request):
    return render(request, "template.html")

Кэширование на уровне шаблонов:

{% load cache %}
{% cache 500 sidebar request.user.id %}
    <div class="sidebar">
        <!-- содержимое здесь кэшируется на 500 секунд -->
    </div>
{% endcache %}

Низкоуровневое кэширование:

from django.core.cache import cache

def expensive_operation():
    cache_key = "user_123_data"
    data = cache.get(cache_key)
    
    if data is None:
        # Выполняем дорогостоящую операцию
        data = process_user_data(user_id=123)
        cache.set(cache_key, data, timeout=3600)  # 1 час
    
    return data

Стратегии инвалидации кэша

Явное удаление:

cache.delete("user_123_data")
cache.delete_pattern("user_*")  # Очистить все записи по паттерну
cache.clear()  # Очистить весь кэш

Автоматическое обновление при изменении данных:

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=User)
def invalidate_user_cache(sender, instance, **kwargs):
    cache.delete(f"user_{instance.id}_data")

Лучшие практики

  • Ключи кэша должны быть уникальны и содержательны: используй f"user_{user_id}_posts_{page}"
  • Устанавливай разумные timeout значения: не кэшируй критичные данные надолго
  • Используй версионирование ключей: добавляй версию в ключ для контролируемой инвалидации
  • Мониторь hit rate: отслеживай эффективность кэша в production
  • Рассмотри использование cache warming: предварительно заполняй кэш критичными данными

Пример продакшена

from django.core.cache import cache
from functools import wraps
import hashlib
import json

def cached_result(timeout=300, version=1):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            # Создаём уникальный ключ
            key_data = f"{func.__name__}:{json.dumps([args, kwargs], sort_keys=True, default=str)}"
            cache_key = f"v{version}:{hashlib.md5(key_data.encode()).hexdigest()}"
            
            result = cache.get(cache_key)
            if result is None:
                result = func(*args, **kwargs)
                cache.set(cache_key, result, timeout)
            return result
        return wrapper
    return decorator

@cached_result(timeout=3600, version=1)
def get_user_stats(user_id):
    return User.objects.filter(id=user_id).values(...).first()

Правильное кэширование может увеличить производительность приложения в 10+ раз, но требует продуманной архитектуры и мониторинга.