首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@cache_page()装饰器在django-redis缓存中的工作

@cache_page()装饰器在django-redis缓存中的工作
EN

Stack Overflow用户
提问于 2017-04-03 11:14:55
回答 1查看 4.2K关注 0票数 2

我正在使用(尝试) redis作为我的django应用程序的缓存。我就是这么做的。

代码语言:javascript
复制
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中的输出。

代码语言:javascript
复制
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"

这是其中一个键下的值,

代码语言:javascript
复制
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."

这是一些序列化的值。

queryset Post.objects.all()是缓存的,我从缓存中获得它没有问题。但我没能理解这个@cache_page()装饰师。

为什么它要在redis数据库里做这么多的键?请解释一下红宝石数据库里的钥匙。我怎么才能知道这起作用了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-09 19:07:07

cache_page装饰师是django装饰师,而不是django-redis装饰师。因此,如果您使用像django中的memcached这样的默认缓存,那么cache_page装饰器就会在memcached中创建相同的密钥。下面是沿着doc字符串的装饰器基本代码:

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

“”装饰器用于试图从缓存中获取页面的视图,如果该页尚未在缓存中,则填充缓存。缓存由URL和来自报头的一些数据进行键控。此外,还有一个键前缀,用于区分多站点设置中的不同缓存区域。例如,您可以使用get_current_site().domain,因为它在Django项目中是唯一的。此外,响应的所有头部都将在缓存时考虑到--就像中间件一样。""“

因此,它本身就是在创建多个键,一个用于标头,另一个用于HTTPResponse内容。它根据标题和内容创建键,这样任何对头的更改都会使缓存无效(例如,在不同的头文件中),即使在url中有相同的参数,但是请求中的内容不同,您将有单独的缓存。不同请求头的示例可以是为不同的登录用户发送关于同一页的登录信息,或者根据标题中显示的移动/桌面用户代理信息为相同的url提供不同的内容。以下是django中的缓存密钥代码

代码语言:javascript
复制
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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43183204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档