1-Django - 缓存
before
Django3.2 + win10 + python3.9
Django缓存框架的管档,写的很好,非常值得一读:https://docs.djangoproject.com/en/3.2/topics/cache/
Django缓存框架的核心目标:https://docs.djangoproject.com/en/3.2/misc/design-philosophies/#cache-design-philosophy
缓存的好处无需多言,所以Django提供了专门的缓存框架来支持各种缓存:
- 不同的缓存粒度,推荐程度由高到低排序:
- 指定视图缓存,粒度适中。
- 模板片段缓存,对模板文件的局部内容进行缓存,粒度较细。
- 全站缓存,粒度最大。
- 更低级别的缓存API,用来缓存Python中的对象(list、dict、模型对象...),没用过,但在某些情况下(我暂时还没想到)很有用的样子。
- 不同的缓存方式,推荐程度由高到低排序:
- 第三方缓存数据库(redis、Memcache),专业的才是最好的嘛。另外,随着内存数据库的发展演变,Memcache不如redis用的多了。
- 本地文件缓存,将渲染好的字符串缓存到文件中,下次查询省了渲染的步骤了,内存不大的小站点非常有用。
- 本地数据库缓存,套路同本地文件缓存。
- 本地内存缓存,内存大了啥都好说。
- 虚拟缓存,用于开发,Django 带有一个实际上并不缓存的“虚拟”缓存——它只是实现了缓存接口而不做任何事情。
由于官档写的很详细了,本篇只做常用的配置和应用示例演示。
缓存配置
缓存参数
这里来列一下公共的缓存参数:
TIMEOUT
:用于缓存的默认超时,以秒为单位。此参数默认为300
秒(5 分钟)。您可以设置TIMEOUT
为None
,默认情况下,缓存键永不过期。值0
会导致键立即过期(实际上是“不缓存”)。OPTIONS
:应该传递给缓存后端的任何选项。每个后端的有效选项列表会有所不同,第三方库支持的缓存后端会将其选项直接传递给底层缓存库。MAX_ENTRIES
:删除旧值之前缓存中允许的最大条目数。此参数默认为300
。CULL_FREQUENCY
:当缓存条目达到MAX_ENTRIES
时,剔除缓存中的比例,这个值必须是整数,默认是3,即剔除三分之一,如果是即剔除一半。存疑的是剔除的策略,我只查到了基于本地内存的缓存剔除策略是LRU,其它的貌似都是随机剔除。
KEY_PREFIX
: 一个字符串,将自动包含(默认添加)到 Django 服务器使用的所有缓存键中。VERSION
:Django 服务器生成的缓存键的默认版本号。KEY_FUNCTION
一个字符串,其中包含一个函数的虚线路径,该函数定义了如何将前缀、版本和密钥组合成最终的缓存密钥。
redis
现在redis数据库用的较多,所以放到最上面!但是django的缓存框架中并没有实现.....但django-redis
模块实现了,所以:
先下载django-redis
模块:
pip install django-redis
然后在settings.py
中进行配置:
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
# "LOCATION": "redis://IP:PORT/可选的数据库参数",
# "LOCATION": "redis://127.0.0.1:6379/0",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {
"max_connections": 100
},
"DECODE_RESPONSES": True, # True返回的数据自动decode
"PASSWORD": "", # 访问redis是否需要密码
}
}
}
具体的使用,参考:https://www.cnblogs.com/Neeo/articles/14269422.html
https://www.cnblogs.com/kai-/p/12403263.html
Memcache
现在由于Memcache用的不多了,这里仅作配置展示。
基于python-memcached模块连接memcache
在settings.py
中配置:
# 通过ip和port链接
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
# 通过sock文件链接
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'unix:/tmp/memcached.sock',
}
}
# 分布式的共享缓存配置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
基于pylibmc模块连接memcache
在settings.py
中配置:
# 通过ip和port链接
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '127.0.0.1:11211',
}
}
# 通过sock文件链接
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '/tmp/memcached.sock',
}
}
# 分布式的共享缓存配置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
本地内存缓存
在配置文件中进行配置即可:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake', # 唯一标识的key
}
}
其他参数参考缓存参数章节。
本地文件缓存
在配置文件中进行配置即可:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
# 如果您使用的是 Windows,请将驱动器号放在路径的开头
# 'LOCATION': 'c:/foo/bar',
}
}
其他参数参考缓存参数章节。
目录路径应该是绝对路径——也就是说,它应该从文件系统的根目录开始。是否在设置的末尾加上斜线并不重要。
确保此设置指向的目录存在并且可读可写,或者它可以由运行 Web 服务器的系统用户创建。
本地数据库缓存
在配置文件中进行配置即可:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table',
}
}
与其他缓存后端不同,数据库缓存不支持在数据库级别自动剔除过期条目。相反,每次调用add()
、set()
或时都会剔除过期的缓存条目。
完事之后,就要创建缓存表了:
python manage.py createcachetable
这将在您的数据库中创建一个表格,该表格具有 Django 的数据库缓存系统所期望的正确格式。表名取自 LOCATION
。
如果是多数据库的话,需要单独配置,参考管档吧:https://docs.djangoproject.com/en/3.2/topics/cache/#multiple-databases
虚拟缓存(用于开发)
项目中使用了缓存,但在开发和调试时,则希望跳过缓存,那么这个虚拟缓存就有用了,你只需要在配置文件中进行配置即可:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
}
}
应用
这里以本地内存缓存作为缓存配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
'OPTIONS': {
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
},
}
}
局部视图缓存
settings.py中配置不变。
应用时有两种,分别是视图中以装饰器的形式和在路由上进行添加。
视图中应用缓存
views.py
:
import time
from django.shortcuts import render, HttpResponse, redirect
# 必须导入缓存装饰器
from django.views.decorators.cache import cache_page
@cache_page(5) # 缓存单位是秒
def index(request):
ctime = time.time()
return HttpResponse(ctime)
urls.py
:
from django.contrib import admin
from django.urls import path, re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
]
浏览器访问的话,每五秒才会刷新一次,因为缓存时间是5秒。
在路由中应用缓存
urls.py
:
from django.contrib import admin
from django.urls import path, re_path
from django.views.decorators.cache import cache_page
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', cache_page(5)(views.index)),
]
views.py
:
import time
from django.shortcuts import render, HttpResponse, redirect
def index(request):
ctime = time.time()
return HttpResponse(ctime)
浏览器访问效果跟上面的一样。
模板片段缓存
可以在模板中对局部进行更细粒度的缓存。
index.html
:
{% load cache %} <!-- 必须声明 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h3>未缓存的</h3>
{{ ctime }}
<h3>使用缓存</h3>
<!-- 缓存内容 -->
{% cache 5 'unique-snowflake' %}
{{ ctime }}
{% endcache %}
</body>
</html>
urls.py
不变:
from django.contrib import admin
from django.urls import path, re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
]
views.py
也不变:
import time
from django.shortcuts import render, HttpResponse, redirect
def index(request):
ctime = time.time()
return render(request, 'index.html', {"ctime": ctime})
更多参考管档吧:https://docs.djangoproject.com/en/3.2/topics/cache/#template-fragment-caching
全栈缓存
全站缓存的配置需要用到中间件,settings.py
:
MIDDLEWARE = [
# 下面这个缓存中间件必须放在所有中间件的最上面
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# 下面这个缓存中间件必须放在所有中间件的最下面
'django.middleware.cache.FetchFromCacheMiddleware',
]
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
'OPTIONS': {
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
},
}
}
# 默认潮湿时间是300秒,我们可以通过CACHE_MIDDLEWARE_SECONDS来修改
CACHE_MIDDLEWARE_SECONDS = 5
# 下面两个是关于key的,保持默认就完了
CACHE_MIDDLEWARE_KEY_PREFIX = ""
CACHE_MIDDLEWARE_ALIAS = ""
see also: https://www.cnblogs.com/wupeiqi/articles/5246483.html