Django ListView - получение последнего связанного объекта и предотвращение кэширования представления или запроса к базе данных в Django

У меня есть модель Campaign и модель CampaignStatus, внешним ключом которой является модель Campaign. Когда кампания редактируется или создается, она проходит через несколько статусов и имеет объект CampaignStatus, связанный с каждым изменением статуса.

Используя CBVs Django, у меня есть представление списка, которое показывает Кампании пользователя, и я хочу передать шаблону самый последний статус в контексте.

Django, похоже, кэширует статус, и я не знаю, как это предотвратить. (Возможно, уместно: представление кампании в Django admin также имеет ту же проблему с кэшированием - я определил метод для получения самого последнего статуса. Представление списка в Django admin CampaignStatus ведет себя как ожидалось, всегда показывая новые статусы, как только они создаются.)

Я хотел бы, чтобы кэш составлял 5 секунд, но он составляет около 3 минут. Как я могу это изменить?

Фрагмент кода из общего ListView, который мы используем:

@method_decorator(cache_page(5), name="dispatch") # single arg is seconds
class CampaignsListView(LoginRequiredMixin, ListView):

    model = Campaign
    paginate_by = 100

    template_name = "writing/user_campaigns.html"
    context_object_name = "user_campaigns"


    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        for i, _ in enumerate(context.get("user_campaigns")):
            campaign = context["user_campaigns"][i]
            campaign_status = CampaignStatus.objects.filter(campaign=campaign).latest("-status")
            context["user_campaigns"][i].status = campaign_status.get_status_display()

        return context

    def get_queryset(self):
        return Campaign.objects.filter(user=self.request.user).order_by("-modified")

    #... some other methods too

Я думаю, что вы можете найти лучшее решение, но вы можете написать сигнал post_save, отбрасывающий аннулирование кэша. Что-то вроде этого:

from django.core.cache import cache
def invalidate_cache_page(
    view: str,
    path_params: Optional[Dict[str, Any]] = None,
    key_prefix: str = '',
    partial: bool = True
) -> None:
    """
    Invalidate page cache.
    """
    cache_key = generate_cache_key(view, path_params, {}, key_prefix, partial)
    if hasattr(cache, 'keys'):
        keys = cache.keys(cache_key) or []
        cache.delete_many(keys)
    else:
        cache.delete(cache_key)

generate_cache_key ваша собственная функция для генерации

Вернуться на верх