144.中间件的原理和定义方式详解
中间件
中间件是在request和response处理过程中的一个插件。比如request到达视图四千,我们可以定义中间件来做一些相关的事情,比如可以判断这个用户有没有登录,如果登录了,就绑定一个对象到request上,也可以在response到达浏览器之前,做一些相关的处理,比如想要统一在response上设置一些cookie信息等。
自定义中间件
中间件所处的位置没有规定,只要是放到项目中即可,一般可以分为两种情况,如果中间件是属于某个app的,那么就可以在这个app下面创建一个python文件用来存储这个中间件,也可以专门创建一个python包,用来存放本项目的所有中间件。创建中间件有两种方式,一种是使用函数,一种是使用类。
1.定义中间件函数
(1)在APP中创建一个python文件,定义与该APP相关的中间件。如果我们想要自己定义的中间件,被django在执行操作的时候使用的话,就要在项目的settings.py文件中的MIDDLEWARE中添加appname.pythonfilename.functionname。函数定义示例代码如下:
from .models import User
def front_user_middlewares(get_response):
print('front_user_middleware初始化执行的代码....')
def middleware(request):
print('request到达view视图之前执行的代码....')
<!--1.在request到达view视图之前,对用户是否进行登录进行判断,如果登录了就在request上绑定一个对象front_user-->
<!-因为python是一个动态执行的语言,即使在对象已经创建完成,也可以对对象随时绑定属性。-->
<!--首先通过session中是否含有一个sessionid,如果有的话,就认为,该用户已经登录了。-->
user_id = request.session.get('user_id')
<!--判断如果user_id存在将执行什么操作,但是这种情况下,同时也存在着user_id不存在的情况,所以我们可以通过try...except...来实现。-->
if user_id:
try:
front_user = User.objects.get(pk=user_id)
request.front_user = front_user
print(request.front_user.username)
except:
request.front_user = None
request.front_user = None
<!--执行get_response(request),就相当于转去执行视图函数了,这一点可以通过在相应的视图函数:print(”这是视图函数中执行的代码“),进行验证-->
response = get_response(request)
print('response到达浏览器之前执行的代码....')
return response
return middleware
在middleware()函数之前的代码是运行该项目之后就会加载的,而middleware()函数中的代码是只有访问网站的时候才会执行的。
(2)之后我们就可以在视图函数中直接使用request上的front_user对象了,示例代码如下:
def index(request):
print("这是index view中的代码")
if request.front_user:
print(request.front_user.username)
return render(request, 'index.html')
def my_list(request):
print('这是my_list中的代码')
if request.front_user:
print(request.front_user.username)
return HttpResponse('success!')
2.定义中间件的类
(1)要想让我们定义的中间件的类起作用的话,同样也需要在settings.py中的MIDDLEWARE中添加appname.pythonfilename.classname。比如,我们想要在request达到view视图函数之前判断用户是否登录,若登录了,就在request上绑定一个front_user对象并且该对象就是新登录的用户。若没有登录,同样为request绑定一个front_user对象,此时就设置为None。示例代码如下:
# 2. 定义一个类
from .models import User
class FrontUserMiddleware(object):
def __init__(self, get_response):
print('front_user_middleware初始化执行的代码....')
<!--需要先保存get_response,以后会用到-->
self.get_response = get_response
def __call__(self, request):
print('request到达view之前执行的代码....')
user_id = request.session.get('user_id')
if user_id:
try:
front_user = User.objects.get(pk=user_id)
request.front_user = front_user
print(request.front_user.username)
except:
request.front_user = None
request.front_user = None
<!--执行get_response()函数就会转去执行view视图函数-->
response = self.get_resonse(request)
print('response到达浏览器之前执行的代码....')
return response
3.即将被遗弃的中间件的定义方式,示例代码如下:
from django.utils.deprecation import MiddlewareMixin
from .models import User
class FrontUserMiddlewareMixin(MiddlewareMixin):
def __init__(self, get_response):
self.get_response = get_response
print('front_user_middleware进行初始化执行的代码....')
# 1. 定义request到达view视图之前执行的操作
def process_request(self, request):
print("request到达view视图之前执行的操作...")
user_id = request.session.get('user_id')
if user_id:
try:
front_user = User.objects.get(pk=user_id)
request.front_user = front_user
print(request.front_user.username)
except:
request.front_user = None
request.front_user = None
# 2. 定义response到达浏览器之前执行的操作
def process_response(self, request, response):
print('response到达浏览器之前执行的操作...')
return response
始于才华,忠于颜值;每件事情在成功之前,看起来都是天方夜谭。一无所有,就是无所不能。