Django cache_page - предварительное заполнение/предварительное кэширование
У меня есть один запрос к БД, который занимает пару секунд в производстве. У меня также есть действие DRF ViewSet
, которое возвращает этот запрос.
Я уже кэширую это action
с помощью cache_page
.
@method_decorator(cache_page(settings.DEFAULT_CACHE_TIMEOUT))
@action(detail=False)
def home(self, request) -> Response:
articles = Article.objects.home()
return Response(serializers.ArticleListSerializer(articles, many=True).data,
headers={'Access-Control-Allow-Origin': '*'})
Проблема в том, что через 15 минут хотя бы одному пользователю нужно ждать 15 секунд для получения ответа. Я хочу предварительно кэшировать это каждые 5 минут в фоновом режиме, чтобы ни одному пользователю не пришлось ждать.
Я использую механизм кэширования по умолчанию.
Моя идея состоит в том, чтобы создать management command
, который будет выполняться с помощью crontab
. Каждые 5 минут он будет вызывать Article.objects.home()
или ViewSet.action
и изменять значение в кэше.
Поскольку это только одна запись, я без колебаний использую кэширование базы данных.
Как бы вы это сделали?
EDIT: поскольку по умолчанию LocMemCache
является однопоточным, я соглашусь с кэшированием базы данных. Я просто не знаю, как вручную кэшировать view
или QuerySet
.
Задача cron или Celery beat (если вы уже используете celery) выглядит как лучший вариант.
Вызов Article.objects.home()
мало что даст, если только вы не будете кэшировать в методе home()
менеджера (что может быть приемлемым вариантом, который может упростить автоматическое обновление кэша).
Для автоматизации обновления кэша представлений вам лучше отправлять фактические запросы на URL из команды управления. Вы также захотите аннулировать кэш перед отправкой запроса, чтобы обновить его.
Кроме того, при планировании частоты выполнения заданий учитывайте таймаут кэша. Вы не захотите обновлять данные слишком рано или слишком поздно.