Работа декоратора @cache_page() в django-redis-cache

Я использую (пытаюсь) redis как кеш для моего приложения django. Вот как я пытаюсь это сделать.

def postview(request):
    post_list = []
    if cache.get("posts") == None:
           post_list = Post.objects.all()
           cache.set("posts", post_list, timeout=None)
    else : 
           post_list = cache.get("posts")
    context = {"post_list" : post_list}
    return render(request, 'post_list.html', context)

@cache_page(60*15, key_prefix="test_cache")
def new(request):
    print("testing")
    return HttpResponse("hello, I am mohammed")

Это вывод в Redis-Cli

luvpreet@DHARI-Inspiron-3542:~/test_venv_wrapper/test_redis$ redis-cli
127.0.0.1:6379> select 2 # I have redis db 2 as backend in django settings
OK
127.0.0.1:6379[2]> keys *
1) ":1:views.decorators.cache.cache_page.cache_test.GET.26488770af116d67b33750e5f304aa3e.d41d8cd98f00b204e9800998ecf8427e.en-us.UTC"
2) ":1:views.decorators.cache.cache_header..d314df08d6409ed165873dfa23271c50.en-us.UTC"
3) ":1:posts"
4) ":1:views.decorators.cache.cache_page..GET.d314df08d6409ed165873dfa23271c50.d41d8cd98f00b204e9800998ecf8427e.en-us.UTC"
5) ":1:views.decorators.cache.cache_header..26488770af116d67b33750e5f304aa3e.en-us.UTC"
6) ":1:views.decorators.cache.cache_page..GET.26488770af116d67b33750e5f304aa3e.d41d8cd98f00b204e9800998ecf8427e.en-us.UTC"
7) ":1:views.decorators.cache.cache_header.cache_test.26488770af116d67b33750e5f304aa3e.en-us.UTC"

Это значение под одним из ключей,

127.0.0.1> get :1:views.decorators.cache.cache_page.cache_test.GET.26488770af116d67b33750e5f304aa3e.d41d8cd98f00b204e9800998ecf8427e.en-us.UTC
"\x80\x02cdjango.http.response\nHttpResponse\nq\x01)\x81q\x02}q\x03(U\x0e_handler_classq\x04NU\b_headersq\x05}q\x06(U\rlast-modifiedU\rLast-ModifiedU\x1dWed, 05 Apr 2017 10:56:58 GMT\x86U\aexpiresU\aExpiresU\x1dWed, 05 Apr 2017 15:06:58 GMT\x86U\x0ccontent-typeU\x0cContent-TypeU\x18text/html; charset=utf-8\x86U\rcache-controlU\rCache-ControlU\rmax-age=15000\x86uU\b_charsetq\aNU\x11_closable_objectsq\b]U\acookiesq\tcdjango.http.cookie\nSimpleCookie\nq\n)\x81q\x0b}q\x0cbU\x06closedq\r\x89U\n_containerq\x0e]q\x0fU\x14Hello, I am Mohammedq\x10aU\x0e_reason_phraseq\x11Nub."

Это некоторое сериализованное значение.

Набор запросов Post.objects.all() кэшируется, и у меня нет проблем с получением этого из кэша. Но я не понимаю этого @cache_page() декоратор.

Почему он делает так много ключей в базе данных redis? Пожалуйста, объясните ключи, сделанные в базе данных Redis. Как я могу узнать, работает это или нет?

1 ответ

Решение

cache_page Декоратор - это декоратор Django, а не декоратор Django-Redis. Итак, если бы вы использовали кеш по умолчанию, такой как memcached в django, декоратор cache_page делал бы те же ключи в memcached. Вот базовый код декоратора вдоль строки документа:

https://github.com/django/django/blob/711123e1cdaf3b08c876c045d8d38decdc7a63d3/django/views/decorators/cache.py

"""Декоратор для представлений, который пытается получить страницу из кеша и заполняет кеш, если страница еще не находится в кеше. Кеш имеет ключ от URL-адреса и некоторые данные из заголовков. Кроме того, есть префикс ключа, который используется для различения разных областей кэша в настройке нескольких сайтов. Например, вы можете использовать домен get_current_site()., поскольку он уникален для проекта Django. Кроме того, будут учитываться все заголовки из заголовка Vary ответа. на кеширование - так же, как промежуточное программное обеспечение. """

Таким образом, по сути он создает несколько ключей, один для заголовков, а другой для содержимого HTTPResponse. Он создает ключи на основе заголовка и содержимого, так что любое изменение в заголовке делает недействительным кеш (например, в случае переменных заголовков), т.е. даже с одинаковыми параметрами в URL, но с разным содержимым в заголовках запросов у вас будут отдельные кэши., Примерами разных заголовков запросов могут быть отправка информации о входе в систему для одной и той же страницы для разных пользователей, вошедших в систему, или предоставление разного контента для одного и того же URL-адреса на основе информации агента пользователя мобильного / настольного компьютера, представленной в заголовках. Вот код ключа кеша в django:

def _generate_cache_key(request, method, headerlist, key_prefix):
    """Return a cache key from the headers given in the header list."""
    ctx = hashlib.md5()
    for header in headerlist:
        value = request.META.get(header)
        if value is not None:
            ctx.update(force_bytes(value))
    url = hashlib.md5(force_bytes(iri_to_uri(request.build_absolute_uri())))
    cache_key = 'views.decorators.cache.cache_page.%s.%s.%s.%s' % (
        key_prefix, method, url.hexdigest(), ctx.hexdigest())
    return _i18n_cache_key_suffix(request, cache_key)


def _generate_cache_header_key(key_prefix, request):
    """Return a cache key for the header cache."""
    url = hashlib.md5(force_bytes(iri_to_uri(request.build_absolute_uri())))
    cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
        key_prefix, url.hexdigest())
    return _i18n_cache_key_suffix(request, cache_key)


def get_cache_key(request, key_prefix=None, method='GET', cache=None):
    """
    Return a cache key based on the request URL and query. It can be used
    in the request phase because it pulls the list of headers to take into
    account from the global URL registry and uses those to build a cache key
    to check against.
    If there isn't a headerlist stored, return None, indicating that the page
    needs to be rebuilt.
    """
    if key_prefix is None:
        key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
    cache_key = _generate_cache_header_key(key_prefix, request)
    if cache is None:
        cache = caches[settings.CACHE_MIDDLEWARE_ALIAS]
    headerlist = cache.get(cache_key)
    if headerlist is not None:
        return _generate_cache_key(request, method, headerlist, key_prefix)
    else:
        return None
Другие вопросы по тегам