4、Django缓存

Django-Redis

安装

pip install django-redis Django

支持 Redis cache/session 后端的全功能组件。充当cache/session Django-Redis依赖于pyredis

作为session后端

SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

作为cache后端

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

应用

MIDDLEWARE = [
    'django.middleware.cache.UpdateCacheMiddleware',  # 放在第一
    # 其他中间件...
    'django.middleware.cache.FetchFromCacheMiddleware',  # 放在最后
]
 
CACHE_MIDDLEWARE_ALIAS = ""          # 用于存储的缓存别名
CACHE_MIDDLEWARE_SECONDS = 600       # 每个页面应缓存的秒数 
CACHE_MIDDLEWARE_KEY_PREFIX = ""     # 如果使用相同的Django安装在多个站点之间共享缓存,请将其设置为站点名称或此Django实例特有的其他字符串,以防止发生密钥冲突。如果你不在乎,请使用空字符串。

单独视图缓存

(记得取消全站缓存中间件配置)

当用户首次访问博客首页时,我们从数据库中提取文章列表,并将其存储到缓存里(常用的是内存,这取决于你的设置)。当用户在单位时间内再次访问首页时, Django先检查缓存是否过期(本例是15分钟), 再检查缓存里文章列表资源是否存在,如果存在,直接从缓存中读取数据, 并渲染模板。

from django.shortcuts import render
from django.views.decorators.cache import cache_page
 
 
@cache_page(60 * 15)  # 秒数,这里指缓存 15 分钟
def index(request):
    article_list = Article.objects.all()
    return render(request, 'index.html', {'article_list': article_list})

模板局部缓存

# 1.引入TemplateTag
{% load cache %}
 
# 2.使用缓存
{% cache 600 name %}  # 第一个参数表示缓存时间,第二个参数是key值(取缓存的时候,需要根据key值取)
  缓存内容
{% endcache %}

在路由URLConf中使用cache

前一节中的范例将视图硬编码为使用缓存,因为 cache_page 在适当的位置对 my_view 函数进行了转换。 该方法将视图与缓存系统进行了耦合,从几个方面来说并不理想。 例如,你可能想在某个无缓存的站点中重用该视图函数,或者你可能想将该视图发布给那些不想通过缓存使用它们的人。 解决这些问题的方法是在 URLconf 中指定视图缓存,而不是紧挨着这些视图函数本身来指定。 完成这项工作非常简单: 在 URLconf 中用到这些视图函数的时候简单地包裹一个 cache_page 。以下是刚才用到过的 URLconf : 这是之前的URLconf:

urlpatterns = ('',
    (r'^foo/(\d{1,2})/$', my_view),
)

# 修改后
from django.views.decorators.cache import cache_page
 
urlpatterns = ('',
    (r'^foo/(\d{1,2})/$', cache_page(my_view, 60 * 15)),
)

其他缓存方式

缓存参数:

  • TIMEOUT: 缓存的默认超时时间,以秒为单位,默认300秒 || None(永不过期)|| 0 (立即过期)

  • OPTIONS

    • MAX_ENTRIES: 删除旧值之前允许缓存的最大条目。默认是 300

    • CULL_FREQUENCY: 当达到 MAX_ENTRIES 时,被删除的条目的比例。实际比例是 1 / CULL_FREQUENCY,所以将 CULL_FREQUENCY 设置为 2,即当达到 MAX_ENTRIES 时将删除一半的条目。这个参数应该是一个整数,默认为 3。值为 0 意味着当达到 MAX_ENTRIES 时,整个缓存将被转储。在某些后端(特别是 database ),这使得缓存速度 快,但代价是缓存未命中更多。

  • KEY_PREFIX: 一个自动包含在 Django 服务器使用的所有缓存键中的字符串(默认为前缀)

  • VERSION :Django 服务器生成的缓存键的默认版本号

  • KEY_FUNCTION : 一个字符串,包含一个函数的点分隔路径,该函数定义了如何将前缀、版本和键组成一个最终的缓存键。

Memcached 缓存实战

pip install pymemcache 
# setting.py
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
        'LOCATION': '127.0.0.1:11211',              # 单个 Memcached
        'KEY_FUNCTION': lambda key,prefix_key,version:"django:%s"%key   #自定义存储格式
        #'LOCATION': 'unix:/tmp/memcached.sock',     # 通过本地 Unix 套接字
        #'LOCATION': [                               # 多个 Memcached 
        #    '172.19.26.240:11211',
        #    '172.19.26.242:11211',
        #]
    }
}

缺点: 基于内存的缓存有一个缺点:因为缓存的数据存储在内存中,如果你的服务器崩溃,数据将丢失

REDIS 缓存实战

MIDDLEWARE = [
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware', # 三项放在中间最上面
]


CACHE_MIDDLEWARE_SECONDS = 60  # default cache time for the whole website
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://redis:6379/1",
        # "LOCATION": "redis://password@redis:6379/1", # 方法一:Add Password 
        'TIMEOUT': 60, # default expire time per api call
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "SOCKET_CONNECT_TIMEOUT": 5,  # in seconds
            "SOCKET_TIMEOUT": 5,  # r/w timeout in seconds
            'MAX_ENTRIES': 10000,
            'KEY_PREFIX': 'recruit-',
            #'PASSWORD': 'password', #  方法二:Add Password 
        }
    }
}

文件系统缓存实战

# 目录路径是绝对路径, 并且具有读写权限
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/var/tmp/django_cache',
        #'LOCATION': 'c:/foo/bar',        # windows
    }
}

本地内存缓存实战

# 适合开发
MIDDLEWARE = [
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware', # 三项放在中间最上面
]


CACHE_MIDDLEWARE_SECONDS = 60  # default cache time for the whole website
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
        'TIMEOUT': 60,
        'OPTIONS': {
            'MAX_ENTRIES': 10000,
            'KEY_PREFIX': 'recruit-',
        }
    }
}

Last updated