中间件

什么是中间件

中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。

Django 中间件作用:

  • 修改请求,即传送到 view 中的 HttpRequest 对象。
  • 修改响应,即 view 返回的 HttpResponse 对象。

中间件的方法

process_request⽅法:在执⾏路由前被调⽤,每个请求上都会调⽤,返回None就依次执⾏,如果返回的值是 HttpResponse对象,不再执⾏后⾯的process_request⽅法,⽽是执⾏当前对 应中间件的process_response⽅法。

process_view⽅法:调⽤视图之前执⾏,每个请求都会调⽤,不主动进⾏返回或返回 HttpResponse对象

process_template_response⽅法:在视图刚好执⾏完后进⾏调⽤,只要视图返回⼀个render⽅法返回的 对象,就会调⽤process_template_response,不主动进⾏返回或返 回HttpResponse对象

process_response方法:所有响应返回浏览器之前调⽤,每个请求都会调⽤,返回 HttpResponse对象

process_exception方法:当视图抛出异常时调⽤,返回None或返回HttpResponse对象

自定义中间件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.utils.deprecation import MiddlewareMixin

class MyMiddlewareMixin(MiddlewareMixin):

def process_request(self, request):
"""
:param request: HttpRequest请求对象
:return: 返回None或返回HttpResponse响应对象,返回None继续执行后面中间件的process_request方法,返回HttpResponse对象调用自己process_response
"""
print("调用了process_request方法")
username = request.session.get('username')
if username:
return None
elif request.path != '/login/':
return redirect('/login/')

加载自定义中间件

在settings中进⾏配置,MIDDLEWARE中添加:应用名.middleware.类名

1
2
3
4
MIDDLEWARE = [
'App.middleware.MyMiddlewareMixin',
...
]

缓存

缓存是⼀类可以更快的读取数据的介质统称,也指其它可以加快数据读取的存储⽅ 式。

在Django中,当⽤户请求到达视图后,视图会先从数据库提取数据放到模板中进 ⾏动态渲染,渲染后的结果就是⽤户看到的⽹⻚。如果⽤户每次请求都从数据库提 取数据并渲染,将极⼤降低性能,不仅服务器压⼒⼤,⽽且客户端也⽆法即时获得 响应。如果能将渲染后的结果放到速度更快的缓存中,每次有请求过来,先检查缓 存中是否有对应的资源,如果有,直接从缓存中取出来返回响应,节省取数据和渲 染的时间,不仅能⼤⼤提⾼系统性能,还能提⾼⽤户体验。

缓存使用场景:缓存主要适⽤于对⻚⾯实时性要求不⾼的⻚⾯。存放在缓存的数 据,通常是频繁访问的,⽽不会经常修改的数据。

缓存方式:数据库、⽂件、内存、redis等

缓存配置

  • 数据库缓存
1
2
3
4
5
6
7
8
9
# settings.py
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table',
}
}
#⽣成缓存表
python manage.py createcachetable
  • redis缓存

安装django-redis插件,安装redis服务器

1
2
3
4
5
6
7
CACHES = {
'default': {
'BACKEND':'django_redis.cache.RedisCache',#指定缓存类型redis缓存
# 'LOCATION':'redis://:123@127.0.0.1:6379/1', #缓存地址,@前⾯是reids的密码,如果没有则去掉
'LOCATION':'redis://127.0.0.1:6379/1', # 没密码
}
}

缓存的使用

视图函数使用

  • 未使用缓存每次刷新都会改成最新时间
1
2
3
4
5
def time(request):
print(111)
time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(time)
return render(request, 'time.html', locals())
  • 加上缓存装饰器,缓存过期了才会更新页面
1
2
3
4
5
6
@cache_page(20)
def time(request):
print(111)
time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(time)
return render(request, 'time.html', locals())

模板局部使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{% load cache %} <!--加载缓存插件-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>缓存时间</title>
</head>
<body>

<!--每次刷新改变-->
<h2>{{ time }}</h2>

{% cache 10 'time2' %}
<!--十秒改变一次-->
<h2>{{ time2 }}</h2>
{% endcache %}
</body>
</html>

全站缓存

在settings里加上中间件,设置超时时间即可,注意:中间件必须加载最前面和最后面。

1
2
3
4
5
6
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
.....
'django.middleware.cache.FetchFromCacheMiddleware',
]
CACHE_MIDDLEWARE_SECONDS = 20 #设置超时时间 20秒

手动设置缓存

使用cache.set(‘名字’, 内容, 超时时间)保存缓存

使用cache.get(‘名字’)获取缓存内容

1
2
3
4
5
6
7
8
9
10
from django.core.cache import cache
def mycache(request):
html = cache.get('time')
# 如果有缓存就取缓存,没有就使用当前时间并写入缓存
if not html:
time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
cache.set('time', time, 5)
html = time
print('当前时间')
return HttpResponse(html)