在大型网站上,如果访问的流量很多,又有很多动态的内容,这样每次获取一个信息都要去访问数据库,效率就会比较低下。这种情况下,一般都会使用缓存机制,首先去缓存里面找,如果有信息,那么直接获取;没有的话才去数据库获取,然后在缓存里面生成一个数据可以给下一次访问使用。


Django里面支持5种常见的缓存设置。

  • 开发测试

  • 本地内存

  • 文件

  • 数据库

  • Memcached(或者Redis)


这些配置都是在settings.py里面配置的。


开发测试,如果希望生产环境配置缓存,测试不需要,那么只需设置为dummycache就行了,他不做任何操作

CACHES = {            
 'default': {                
     'BACKEND': 'django.core.cache.backends.dummy.DummyCache',     # 引擎
     'TIMEOUT': 300,                                               # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
     'OPTIONS':{                    
         'MAX_ENTRIES': 300,                                       # 最大缓存个数(默认300)
         'CULL_FREQUENCY': 3,                                      # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)                },                'KEY_PREFIX': '',                                             # 缓存key的前缀(默认空)
         'VERSION': 1,                                             # 缓存key的版本(默认1)
         'KEY_FUNCTION' 函数名                                      # 生成key的函数(默认函数会生成为:【前缀:版本:key】)            }
        }


本地内存

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': os.path.join(BASE_DIR,'cache')
    }
}



文件

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': os.path.join(BASE_DIR,'cache')
    }
}


数据库

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': os.path.join(BASE_DIR,'cache')
    }
}


Memcache 或者Redis,我们甚至可以同时设置多个不同的cache位置

CACHES = {
    "redis": {
        "BACKEND": "redis_cache.cache.RedisCache",
        "LOCATION": "127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "redis_cache.client.DefaultClient",
        }
    },
    'memcache': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
        'options': {
            'MAX_ENTRIES': 1024,
        }
    },
     'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
        'options': {
            'MAX_ENTRIES': 1024,
        }
    }}



如何应用呢?

Django 提供了3个级别的应用。


全部缓存

这种方式需要添加两条中间件,注意一上一下的

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.filebased.FileBasedCache',
        'LOCATION': os.path.join(BASE_DIR,'cache')
    }
}



创建一个文件夹来存放缓存


wKioL1mwun7ht8fwAAAaZK0mJ4s299.png


views.py

def cache(request):
    import time
    ctime = time.time()
    return render(request, 'cache.html', {'ctime': ctime})


cache.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>{{ ctime }}</h1>
    <h1>{{ ctime }}</h1>
</body>
</html>

这样子整个页面都给缓存了


如果希望更细粒度的缓存,我们可以使用装饰器来装饰对应的视图函数

去掉中间件的设置,然后在我们的视图函数上

from django.views.decorators.cache import cache_page
@cache_page(10)
def cache(request):
    import time
    ctime = time.time()
    return render(request, 'cache.html', {'ctime': ctime})


这样数据缓存10秒之后才会重新刷新

wKiom1mwvyexaZcmAAAfNKer2WU627.png



我们还可以再更细粒度的缓存。这次我们在对应的模板文件上针对某个数据进行缓存。


去掉装饰器,然后在cache.html修改

{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>{{ ctime }}</h1>
    <h1>{{ ctime }}</h1>
{##}
     {% cache 5 c1 %}
        <h1>{{ ctime }}</h1>
     {% endcache %}
</body>
</html>


执行操作,上面两个数据是实时更新的,第三个数据缓存5秒之后才更新

wKiom1mwvyiCakVBAAAq9D1t-hk980.png