自定义使用 Redis


# utils/redis_pool.py

# 使用模块的单例模式创建连接池

import redis

# POOL = redis.ConnectionPool(host='127.0.0.1', port=6379, max_connections=1000, decode_responses=True)  # 设置连接池
POOL = redis.ConnectionPool(max_connections=1000, decode_responses=True)  # 设置连接池

# views.py

import redis
from django.shortcuts import render, HttpResponse
from utils.redis_pool import POOL


def index(request):
    conn = redis.Redis(connection_pool=POOL)  # 去连接池中获取连接
    conn.set('index', 'index的缓存数据')  # 设置缓存
    return HttpResponse('设置缓存成功_index')


def order(request):
    conn = redis.Redis(connection_pool=POOL)  # 去连接池中获取连接
    conn.set('order', 'order的缓存数据')  # 设置缓存
    return HttpResponse('设置缓存成功_order')

使用第三方组件


1. django-redis的安装

pip3 install django-redis -i https://pypi.douban.com/simple # 使用豆瓣的镜像

2. 在Django中配置redis

  • 可以配置其他或多个缓存 -> 如: Memcache、Redis、等 -> 前提是要下载好对应的django处理该缓存的模块

# settings.py

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379',  # ip+端口号的设置,本地ip: 127.0.0.1,默认redis端口号: 6379
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            'CONNECTION_POOL_KWARGS': {
                'max_connections': 1000,  # 最大连接数
                'decode_responses': True,  # 是否自动进行解码, 注意: 在使用全站/单视图/局部缓存的时候不能设置该配置否则会报utf-8的错误
            }
# 'PASSWORD': '密码',  # 密码: 如果没有可以不进行配置
        }
    },
# 为了演示所创建的缓存配置,ip+端口都是乱写的
    'r2_cache': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://47.0.0.1:6379',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            'CONNECTION_POOL_KWARGS': {
                'max_connections': 100,
                'decode_responses': True,
            }
# 'PASSWORD': '密码',
        }
    },
 # ……
}

3. 在Django中使用redis

# views.py

from django.shortcuts import render, HttpResponse
from django_redis import get_redis_connection  # 获取连接池中的连接方法


def index(request):
    conn = get_redis_connection('default')  # 使用 django_redis 模块所提供的 get_redis_connection 方法,获取 default 缓存连接池的连接
    conn.set('index', 'index的缓存数据')  # 设置缓存
    return HttpResponse('设置缓存成功_index')


def order(request):
    conn = get_redis_connection('r2_cache')  # 使用 django_redis 模块所提供的 get_redis_connection 方法,获取 r2_cache 缓存连接池的连接
    conn.set('order', 'order的缓存数据')  # 设置缓存
    return HttpResponse('设置缓存成功_order')

# test.py

from django_redis import get_redis_connection  # 获取连接池中的连接方法

conn = get_redis_connection('default')  # 使用 django_redis 模块所提供的 get_redis_connection 方法,获取 default 缓存连接池的连接
index_data = conn.get('index')  # 获取缓存
print(index_data)  # index的缓存数据

高级使用


1. 全站缓存 -> 谨慎使用

  • 注意: 全站缓存在浏览器上是无法清除的,因为缓存是写在服务器上

  • 全站缓存的原理: 使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存

  • 中间件示意图


  • 中间件的配置

    • FetchFromCacheMiddleware 中间件的说明:
      • FetchFromCacheMiddleware 中间件的作用: 检测缓存中是否有当前页面的缓存,如果有直接进行返回,如果没有就会从数据库中获取对应的数据,然后返回
      • FetchFromCacheMiddleware 中间件中只有 process_request 方法
      • FetchFromCacheMiddleware 中间件必须放在所有中间件的后面,因为必须要经过认证等中间件后才能获取到页面

    • UpdateCacheMiddleware 中间件的说明:
      • UpdateCacheMiddleware 中间件的作用: 将从数据库中获取到的数据添加到缓存中
      • UpdateCacheMiddleware 中间件中只有 process_response 方法
      • UpdateCacheMiddleware 中间件必须放在所有中间件的第一位,因为在返回给浏览器之前必须执行session等中间件设置 session、cookie、状态码等,最后才执行 UpdateCacheMiddleware 中间件设置缓存,让后返回给浏览器

# settings.py

MIDDLEWARE = [
    'django.middleware.cache.UpdateCacheMiddleware',
# 其他中间件……
    'django.middleware.cache.FetchFromCacheMiddleware',
]

CACHE_MIDDLEWARE_ALIAS = 'default'  # 缓存别名(即: 使用哪一个你所配置的缓存),默认值default
CACHE_MIDDLEWARE_SECONDS = 10  # 缓存时间,单位秒
CACHE_MIDDLEWARE_KEY_PREFIX = ""  # 如果缓存被多个使用相同 Django 安装的站点共享,配置此参数为站点名称或其它能代表站点的唯一字符串,以防止key冲突。如果不在意,可为空

  • 缓存的配置 -> 使用redis缓存,可以不进行配置使用Django默认的

# settings.py

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379',  # ip+端口号的设置,本地ip: 127.0.0.1,默认redis端口号: 6379
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            'CONNECTION_POOL_KWARGS': {
                'max_connections': 1000,  # 最大连接数
# 'decode_responses': True,  # 是否自动进行解码, 注意: 在使用全站/单视图/局部缓存的时候不能设置该配置否则会报utf-8的错误
            }
# 'PASSWORD': '密码',  # 密码: 如果没有可以不进行配置
        }
    }
}

  • 测试是否缓存了

    • 如果时间没有改变,则代表缓存成功

# views.py

import time
from django.shortcuts import render, HttpResponse


def index(request):
    ctime = str(time.time())
    return HttpResponse('index_%s' % ctime)


def order(request):
    ctime = str(time.time())
    return HttpResponse('order_%s' % ctime)

2. 单视图缓存

  • 注意: 单视图缓存在浏览器上是无法清除的,因为缓存是写在服务器上

  • 单视图缓存的优先级比全局缓存要高,如果设置了但是视图缓存,那么全局缓存对该视图则无效

  • 缓存的配置 -> 使用redis缓存,可以不进行配置使用Django默认的

# settings.py

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379',  # ip+端口号的设置,本地ip: 127.0.0.1,默认redis端口号: 6379
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            'CONNECTION_POOL_KWARGS': {
                'max_connections': 1000,  # 最大连接数
# 'decode_responses': True,  # 是否自动进行解码, 注意: 在使用全站/单视图/局部缓存的时候不能设置该配置否则会报utf-8的错误
            }
# 'PASSWORD': '密码',  # 密码: 如果没有可以不进行配置
        }
    }
}

  • 使用Django所提供的装饰器实现单视图缓存

# views.py

import time
from django.shortcuts import render, HttpResponse
from django.views.decorators.cache import cache_page  # 局部缓存的装饰器


@cache_page(10) # 使用装饰器设置局部缓存,参数: 超时时间,单位秒
def index(request):
    ctime = str(time.time())
    return HttpResponse('index_%s' % ctime)


def order(request):
    ctime = str(time.time())
    return HttpResponse('order_%s' % ctime)

3. 局部视图缓存

  • 注意: 局部缓存在浏览器上是无法清除的,因为缓存是写在服务器上

  • 局部视图缓存,即缓存页面的某一部分内容

  • 缓存的配置 -> 使用redis缓存,可以不进行配置使用Django默认的

# settings.py

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379',  # ip+端口号的设置,本地ip: 127.0.0.1,默认redis端口号: 6379
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            'CONNECTION_POOL_KWARGS': {
                'max_connections': 1000,  # 最大连接数
# 'decode_responses': True,  # 是否自动进行解码, 注意: 在使用全站/单视图/局部缓存的时候不能设置该配置否则会报utf-8的错误
            }
# 'PASSWORD': '密码',  # 密码: 如果没有可以不进行配置
        }
    }
}

  • 局部视图缓存的使用

# views.py

import time
from django.shortcuts import render, HttpResponse


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

# 用法

1. 引入TemplateTag

{% load cache %}

2. 使用缓存

{% cache 缓存时间(单位秒) '缓存key' %}
    缓存内容
{% endcache %}

# index.html

{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% cache 10 'time' %}
        <h1>{{ ctime }}</h1>
{% endcache %}
    <p>{{ ctime }}</p>
</body>
</html>