Django отключить низкоуровневое кэширование с помощью менеджера контекста - PullRequest
0 голосов
/ 05 марта 2020

Один из моих методов в проекте, над которым я работаю, выглядит следующим образом:

from django.core.cache import cache
from app import models

def _get_active_children(parent_id, timestamp):
    children = cache.get(f"active_seasons_{parent_id}")
    if children is None:
        children = models.Children.objects.filter(parent_id=parent_id).active(
            dt=timestamp
        )
        cache.set(
            f"active_children_{parent_id}",
            children,
            60 * 10,
        )
    return children

Проблема в том, что я не хочу, чтобы кэширование происходило, когда этот метод вызывается из командной строки ( это внутри задачи). Поэтому мне интересно, есть ли способ отключить кэширование этой формы?

В идеале я хочу использовать менеджер контекста, чтобы любые вызовы кеша внутри контекста игнорировались (или помещались в кеш DummyCache / LocalMem, который не влиял бы на мой основной кеш Redis).

Я рассмотрел pasisng skip_cache=True с помощью методов, но это довольно хрупко, и я уверен, что есть более элегантное решение. Кроме того, я попытался использовать mock.patch, но не уверен, что это работает вне тестовых классов.

Мое идеальное решение будет выглядеть примерно так:

def task():
    ...
    _get_active_children(parent_id, timestamp):

with no_cache:
    task()

1 Ответ

0 голосов
/ 05 марта 2020

У меня есть решение (но я думаю, что есть лучшее):

from unittest.mock import patch

from django.core.cache.backends.dummy import DummyCache
from django.utils.module_loading import import_string


def no_cache(module_str, cache_object_str='cache'):
    """ example usage: with no_cache('app.tasks', 'cache'): """
    module_ = import_string(module_str)
    return patch.object(module_, cache_object_str, DummyCache('mock', {}))

Вдохновленный этим .

...