# 缓存
- 缓存的作用:
- 用户发出一个 HTTP 请求时,网站可能要经过查询数据库、加工数据、渲染前端文件等环节,才能返回 HTTP 响应报文。
- 如果将中间环节的数据缓存起来,当用户发出一个相同的 HTTP 请求时,不再重复生成数据,而是使用缓存的数据,就可以大幅减少响应耗时。
- Django 支持在 QuerySet 中缓存数据,避免重复查询数据库,还支持通用的缓存后端。
- 本文主要介绍如何使用缓存后端来缓存 HTTP 响应报文、Python 对象。
# 缓存后端
Django 支持多种缓存后端:
- Memcached 内存服务器
- Django 当前使用的数据库
- 本地文件
- 本地内存
- 默认采用这种方案。
- 它是线程安全的。但每个进程都会创建一份实例,不能跨进程共享缓存。
- 它基于 LRU 算法删除缓存的数据。
- 配置如下:
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', # 'LOCATION': 'unique-name', # 如果存在多个本地内存缓存,则需要给它们指定不同的名称 # 以下参数适用于所有类型的缓存 # 'TIMEOUT': 300, # 超时时间 # 'OPTIONS': { # 其它选项 # 'MAX_ENTRIES': 1000 # 最多缓存多少条数据,超过该数量则删掉旧数据 # } } }
- 虚拟缓存
- 它并不会实际存储数据,主要用于调试。
- 配置如下:
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', } }
- 其它自定义的缓存后端
# 缓存视图
在 settings.py 中加入以下配置即可缓存所有 Web 页面:
MIDDLEWARE = [ 'django.middleware.cache.UpdateCacheMiddleware', # 最先导入 ..., 'django.middleware.cache.FetchFromCacheMiddleware', # 最后导入,用于缓存状态码为 200 的 GET、HEAD 响应报文,会自动设置 Cache-Control 等 Headers ] CACHES = { # 定义缓存 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', } } CACHE_MIDDLEWARE_ALIAS = 'default' # 采用哪个缓存 CACHE_MIDDLEWARE_SECONDS = 300 # 指定每个页面的缓存超时时间,作用于全局所有页面 CACHE_MIDDLEWARE_KEY_PREFIX = ''
可以单独配置某个视图的缓存超时时间:
from django.views.decorators.cache import cache_page @cache_page(60) def myview(request): ...
或者在 urls.py 中配置:
from django.views.decorators.cache import cache_page from . import view urlpatterns = [ path('home/', cache_page(60)(view.myview)), ]
# 缓存 Python 对象
将 Python 对象写入缓存:
>>> from django.core.cache import cache # 调用当前的缓存实例 >>> cache.set('key1', 'hello') # 缓存一对 key、value >>> cache.set('key1', 'world', 5) # 可以自定义超时时间,默认使用全局的超时时间
- 缓存的 key 必须是 str 类型,value 可以是任意 Python 对象。
- 超时时间的单位为秒。设置为 None 则一直不过期,设置为 0 则不缓存。
set() 方法总是会新增或覆盖缓存,而 add() 方法会在指定的 key 不存在时才新增缓存。
>>> cache.add('key2', 'hello') True # 返回值为 True 表示操作成功 >>> cache.add('key2', 'hello') False
读取缓存:
>>> cache.get('key1') # 获取一个 key 对于的 value 'hello world' >>> cache.get('key3') # 如果指定的 key 不存在,或已超时,则返回值为 None >>> cache.get('key3', 'miss') # 可以指定返回的默认值 'miss'
更新一个 key 的超时时间:
>>> cache.touch('key1', 10) True
主动删除缓存:
>>> cache.delete('key1') True >>> cache.delete('key1') False
- 调用
cache.clear()
会清空所有缓存。
- 调用
同时操作多个 key :
>>> cache.set_many({'a': 1, 'b': 2, 'c': 3}) [] >>> cache.get_many(['a', 'b', 'c']) {'a': 1, 'b': 2, 'c': 3} >>> cache.delete_many(['a', 'b', 'c'])