下面是针对“浅谈Django 页面缓存的cache_key是如何生成的”的完整攻略,希望对您有所帮助:
简介
Django 是一个流行的 Python Web 框架,具有完善的开发文档和强大的社区支持。在 Django 中,缓存机制是提高 Web 性能的重要手段之一,其中页面缓存是应用最为广泛的缓存方式之一,Django 内置了 cache_page 装饰器和 cache API 函数来实现页面缓存,而缓存的 key 是实现缓存的关键。
生成 cache_key 的方法
在 Django 中,cache_key 是由三部分组成的:
- 缓存 key 的命名空间
- 缓存 key 的版本号
- 实际缓存 key 的值
其中,命名空间和版本号可以省略,默认使用 settings.CACHE_MIDDLEWARE_KEY_PREFIX 和 settings.CACHE_MIDDLEWARE_SECONDS 两个设置。
命名空间
命名空间是可选的,如果设置了 settings.CACHE_MIDDLEWARE_KEY_PREFIX,那么它会作为缓存 key 的命名空间,可以用来区分不同的应用。
例如,假设我们有两个应用:blog 和 shop。这时我们可以在 settings.py 中设置:
CACHE_MIDDLEWARE_KEY_PREFIX = 'blog'
这样,缓存 key 的命名空间就是 blog,blog 应用的缓存 key 就和 shop 应用的缓存 key 不会混淆。
版本号
版本号也是可选的,如果设置了 settings.CACHE_MIDDLEWARE_SECONDS,那么它会作为缓存 key 的版本号,可以用来控制缓存的过期时间。
例如,假设我们设置 settings.CACHE_MIDDLEWARE_SECONDS 为 60,即缓存时间为 60 秒,这时可以得到缓存 key 的版本号为 60。
缓存 key 的值
缓存 key 的值是页面缓存的主要内容,它是由请求的 URL 和请求的参数组成的。Django 使用了一个叫做 URL 化的方式来生成缓存 key。
具体来说,URL 化指的是将 URL 中的特殊字符进行编码,比如将斜杠 ( / ) 替换成下划线 ( _ ),将问号 ( ? ) 替换成 exclamation point ( ! ),以此类推。URL 化是为了避免缓存 key 中出现特殊字符,导致缓存失败。
在 Django 中,URL 化的主要逻辑在 django.utils.cache.generate_cache_key 函数中实现,该函数会将请求的 URL 和参数,以及命名空间和版本号组合成唯一的缓存 key。
下面是 generate_cache_key 函数的源代码:
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, None)
if value is not None:
ctx.update(force_bytes(value))
if key_prefix:
if callable(key_prefix):
key_prefix = key_prefix(request)
key_prefix = force_bytes(key_prefix)
ctx.update(key_prefix)
if method not in ('GET', 'HEAD', 'POST'):
method = 'GET'
path = request.get_full_path()
if settings.USE_I18N:
path = normalize_path(path)
ctx.update(force_bytes(method))
ctx.update(force_bytes(path))
return ctx.hexdigest()
从源代码可以看出,generate_cache_key 函数会获取请求的各种信息,包括请求方法、请求头、请求的 URL 和参数,然后使用 hashlib.md5 函数进行哈希运算,生成缓存 key。
示例说明
下面通过两个示例来说明 Django 中页面缓存的 cache_key 是如何生成的。
示例1: 带查询参数的URL
假设有一个带查询参数的URL: http://example.com/test/?q=demo,那么它的 cache_key 就是:
.../_v_cache_test_60_GET/test/!q=demo
其中:
- _v_cache 表示版本号的命名空间,可以省略
- test 表示 Django view 的名称,这是缓存 key 的命名空间
- 60 表示缓存 key 的版本号,这里的值来自于 settings.CACHE_MIDDLEWARE_SECONDS
- GET 表示请求的方法
- test/!q=demo 表示 URL 化的请求 URL 和参数
示例2: 带斜杠的URL
假设有一个带斜杠的URL: http://example.com/test/?p=/demo,那么它的 cache_key 就是:
.../_v_cache_test_60_GET/test/!p%3D_demo
其中:
- _v_cache 表示版本号的命名空间,可以省略
- test 表示 Django view 的名称,这是缓存 key 的命名空间
- 60 表示缓存 key 的版本号,这里的值来自于 settings.CACHE_MIDDLEWARE_SECONDS
- GET 表示请求的方法
- test/!p%3D_demo 表示 URL 化的请求 URL 和参数,它改变了参数中斜杠 ( / ) 的表示方式,避免了出现特殊字符。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈Django 页面缓存的cache_key是如何生成的 - Python技术站