django 学习笔记 使用 redis 缓存加快页面的响应速度-附一个简单的实例
前言:「redis」基于内存的数据库,响应速度到远远快于基于硬盘的「mysql」,使用方式是:直接从「redis」中读取数据,如果「redis」中没有我们需要的数据或者数据更新过,则从「mysql」中读取数据,加载到「redis」中,在将数据返回到前端页面。数据的第一次查询和加载会慢一点,但后面会快很多。
「redis」的配置
「redis」官方并不支持「windows」操作系统,需要通过「Github」获取适配「windows」版本的「redis」
「windows」版本的「redis」下载链接,下载「Redis-x64-3.2.100.msi」就好了,下载完成后,点击安装(默认配置就可以)。
在「管理员权限cmd」中「cd」到你的安装目录:运行「redis-server.exe --service-install redis.windows.conf」将「redis」设置成系统服务。启动服务「net start redis」,停止服务「net stop redis」
连接「redis」:「redis-cli -h 127.0.0.1 -p 6379」后面跟的参数都是可以自己设置的。默认情况下没有密码的。如果自是本地连接,后面的参数都可省略
默认参数的设置:通过「CONFIG GET」和「CONFIG SET」来获取和设置参数,也可以直接打开安装目录下的「redis-windows.conf」来进行设置。
需要设置的参数:
1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
>>> daemonize no
2. 绑定的主机地址,如果你想进行远程访问,请在配置文件中将这一行注释掉
>>> bind 127.0.0.1
3. 设定密码,比如将密码设置成 123456(配置文件中修改)
>>> requirepass 123456
「django」中的使用
有大神做好了一个连接二者的模块「django-redis」,只需在你「python」项目的虚拟环境中进行「pip」安装即可。
不过要注意安装的版本哦,如果你用的「django」的版本比较低的话,最新版的「django-redis」会强制更新的「django」。所以最好看一下「django-redis」的文档。链接在这里,里面有中文翻译版的
安装完成后的配置
主要是在「django」项目下的「settings.py」中进行设置。参数什么的按官方文档中的来。下面贴出我的设置:
# 配置 redis 缓存
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"PASSWORD": '123456',
# 套接字建立连接超时设置为 5 秒
"SOCKET_CONNECT_TIMEOUT": 5, # in seconds
# 套接字连接建立后的读写操作超时设置为 5 秒
"SOCKET_TIMEOUT": 5, # in seconds
# memcached 异常行为
# 在某些情况下, redis 只作为缓存使用, 当它关闭时如果你不希望触发异常.
# 这是 memcached backend 的默认行为, 你可以使用 django-redis 模拟这种情况.
"IGNORE_EXCEPTIONS": True,
}
}
}
# 配置 django-redis 缓存后端作为 Django 的 session 后端
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
# 当然,你也可以给所有缓存配置相同的忽略行为:
# DJANGO_REDIS_IGNORE_EXCEPTIONS = True
# 当使用 IGNORE_EXCEPTIONS 或者 DJANGO_REDIS_IGNORE_EXCEPTIONS 参数忽略异常时,
# 你也许会用到 DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS 参数来配置日志异常:
DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS = True
# 如果你想设置指定的 logger 输出异常, 只需要设置全局变量 DJANGO_REDIS_LOGGER 为 logger 的名称或其路径即可.
DJANGO_REDIS_LOGGER = 'memcached.error.logger'
# django-redis 支持永不超时设置. 其表现和 django backend 指定的相同:
# timeout=0 立即过期
# timeout=None 永不超时
# django-redis 支持 redis 分布式锁. 锁的线程接口是相同的, 因此你可以使用它作为替代.
# 使用 python 上下文管理器分配锁的例子:
#
# with cache.lock("somekey"):
# do_some_thing()
# django-redis 支持使用全局通配符的方式来检索或者删除键.
# 使用通配符搜索的例子
# >>> from django.core.cache import cache
# >>> cache.keys("foo_*")
# ["foo_1", "foo_2"]
# 你可以使用 iter_keys 取代 keys 方法, iter_keys 将返回匹配值的迭代器, 你可以使用迭代器高效的进行遍历.
# >>> from django.core.cache import cache
# >>> cache.iter_keys("foo_*")
# <generator object algo at 0x7ffa9c2713a8>
# >>> next(cache.iter_keys("foo_*"))
# "foo_1"
# 如果要删除键, 使用 delete_pattern 方法, 它和 keys 方法一样也支持全局通配符, 此函数将会返回删掉的键的数量
# 使用 delete_pattern 的例子
# >>> from django.core.cache import cache
# >>> cache.delete_pattern("foo_*")
「redis」默认会有 16 个数据库。默认连接的是第一个库「0 号库」。这是使用的是它的第二个库「1 号库」,你也可以自己设置库的数量和具体使用哪个库。「redis」的客户端通过命令「SELECT」来选着使用哪个库。
简单的应用-留言板的留言功能和留言展示功能
新建应用「message_board」
「models.py」下写个模型类
# _*_ coding: utf-8 _*_
from django.db import models
from django.utils import timezone
class Message(models.Model):
name = models.CharField(max_length=20, verbose_name='留言者姓名')
email = models.EmailField(max_length=30, verbose_name='留言者邮箱')
message = models.TextField(verbose_name='留言内容')
add_time = models.DateTimeField(default=timezone.now, verbose_name='添加时间')
class Meta:
verbose_name = u'留言'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
「views.py」下写连个视图类来处理留言提交和留言的显示
# _*_ coding: utf-8 _*_
import json
from django.shortcuts import render
from django.views import View
from django.core.cache import cache
from .models import Message
from .forms import MessageForm
# 设定一个全局变量来指示数据数据是否有更新,这个写感觉有点问题,但是毕竟简单粗暴,对于这个实例够用
status = False
class GetMessage(View):
def get(self, request):
return render(request, 'message_board/get_message.html', {})
def post(self, request):
global status
# 验证填入的邮箱合规
message_form = MessageForm(request.POST)
if message_form.is_valid():
message = Message()
message.name = request.POST.get('name', '')
message.email = request.POST.get('email', '')
message.message = request.POST.get('message', '')
message.save()
# 数据更新成功,将标志设为 True
status = True
return render(request, 'message_board/get_message.html', {
'msg': json.dumps('留言提交成功!')
})
else:
return render(request, 'message_board/get_message.html', {
'msg': json.dumps('留言提交失败,邮箱地址不正确!'),
'message_form': message_form
})
class MessageDisplay(View):
def get(self, request):
global status
# 使用 redis 来缓存数据
# 设定一个 key:用来作为 redis 中的键
key = 'messages'
# 判断数据是否更新以及缓存中是否有我们需要的数据
if not status and cache.has_key(key):
data = cache.get(key)
# 没有则从「mysql」中更新数据,并更新缓存
else:
data = Message.objects.all()
cache.set(key, data, timeout=5*60)
status = False
return render(request, 'message_board/display_message.html', {
'messages': data,
})
我自己在写了两个简单前端页面,展示效果如下:
留言的展示效果: