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

Что такое кеширование запросов в Django?

1.0 Junior🔥 221 комментариев
#Тестирование

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

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

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

Кеширование запросов в Django

Кеширование запросов — это техника оптимизации производительности, при которой результаты SQL-запросов сохраняются в памяти (кэше) для быстрого доступа в будущем. Это позволяет избежать повторных обращений к базе данных для одних и тех же данных, значительно снижая нагрузку на БД и время отклика приложения.

Уровни кеширования в Django

Django предоставляет несколько уровней кеширования:

  1. Кеширование на уровне БД — кэш результатов ORM запросов
  2. Кеширование представлений (View caching) — сохранение полного вывода представления
  3. Кеширование шаблонов — кэш отдельных блоков шаблонов
  4. Низкоуровневое кеширование — прямая работа с кэшем через cache API

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

Django поддерживает разные бэкенды кеширования:

# settings.py
CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.redis.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
    }
}

Доступные бэкенды: Redis, Memcached, файловая система, локальная память (разработка).

Кеширование представлений

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)  # Кэш на 15 минут
def my_view(request):
    data = ExpensiveModel.objects.all()
    return render(request, 'template.html', {'data': data})

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

from django.core.cache import cache

# Сохранение в кэш
cache.set('user_profile_123', user_data, timeout=300)  # 5 минут

# Получение из кэша
user_data = cache.get('user_profile_123')

# Получение или вычисление
data = cache.get_or_set('expensive_data', expensive_function, 600)

# Удаление из кэша
cache.delete('user_profile_123')

# Очистка всего кэша
cache.clear()

Кеширование запросов ORM

# Ручное кеширование результатов запроса
def get_user_posts(user_id):
    cache_key = f'user_posts_{user_id}'
    posts = cache.get(cache_key)
    
    if posts is None:
        posts = Post.objects.filter(user_id=user_id)
        cache.set(cache_key, list(posts), 3600)  # Кэш на час
    
    return posts

Кеширование шаблонов

{% load cache %}

{% cache 500 sidebar user.id %}
    <div class="sidebar">
        <!-- дорогостоящий контент -->
    </div>
{% endcache %}

Инвалидация кэша

Критически важно корректно инвалидировать (очищать) кэш при обновлении данных:

def update_user_profile(user_id, data):
    user = User.objects.get(id=user_id)
    for key, value in data.items():
        setattr(user, key, value)
    user.save()
    
    # Инвалидируем кэш
    cache.delete(f'user_profile_{user_id}')
    cache.delete(f'user_posts_{user_id}')

Паттерны кеширования

Cache-Aside (Lazy Loading) — самый распространённый паттерн:

  • Проверь кэш
  • Если есть — верни
  • Если нет — загрузи из БД, сохрани в кэш

Write-Through — при записи обновляй кэш одновременно:

def save_user(user):
    user.save()
    cache.set(f'user_{user.id}', user, 3600)

Практические советы

  • Используй Redis или Memcached для production, не файловую систему
  • Выбирай разумные timeout'ы (не слишком короткие, не слишком длинные)
  • Инвалидируй кэш при каждом обновлении данных
  • Используй версионирование ключей для безболезненного обновления формата
  • Мониторь hit rate кэша (какой процент запросов из кэша)
  • Избегай cache stampede — когда многие запросы одновременно заново вычисляют значение после истечения TTL

Кеширование — мощный инструмент для масштабирования, но требует тщательного проектирования инвалидации данных.

Что такое кеширование запросов в Django? | PrepBro