Django补充——中间件请求的生命周期等
Posted Wang-Vee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django补充——中间件请求的生命周期等相关的知识,希望对你有一定的参考价值。
一:中间件
django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下图。
与mange.py在同一目录下的文件夹 wupeiqi/middleware下的auth.py文件中的Authentication类
中间件中可以定义四个方法,分别是:
- process_request(self,request)
- process_view(self, request, callback, callback_args, callback_kwargs)
- process_template_response(self,request,response)
- process_exception(self, request, exception)
- process_response(self, request, response)
以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。
自定义中间件:
1、创建中间件类
class RequestExeute(object): def process_request(self,request): pass def process_view(self, request, callback, callback_args, callback_kwargs): i =1 pass def process_exception(self, request, exception): pass def process_response(self, request, response): return response
""" class M1(MiddlewareMixin): def process_request(self,request): print(\'m1.process_request\') def process_view(self,request, view_func, view_func_args, view_func_kwargs): print(\'m1.process_view\') def process_exception(self,request,exception): print(\'m1.process_exception\') def process_response(self,request,response): print(\'m1.process_response\') return response def process_template_response(self,request,response): print(\'m1.process_template_response\') return response class M2(MiddlewareMixin): def process_request(self, request): print(\'m2.process_request\') def process_view(self, request, view_func, view_func_args, view_func_kwargs): print(\'M2.process_view\') def process_exception(self,request,exception): print(\'m2.process_exception\') return HttpResponse(\'开发的程序员已经被打死\') def process_response(self, request, response): print(\'m2.process_response\') return response def process_template_response(self,request,response): print(\'m2.process_template_response\') return response """ from django.shortcuts import HttpResponse,redirect class MiddlewareMixin(object): def __init__(self, get_response=None): self.get_response = get_response super(MiddlewareMixin, self).__init__() def __call__(self, request): response = None if hasattr(self, \'process_request\'): response = self.process_request(request) if not response: response = self.get_response(request) if hasattr(self, \'process_response\'): response = self.process_response(request, response) return response class M1(MiddlewareMixin): def process_response(self, request, response): print(\'m2.process_response\') return response class M2(MiddlewareMixin): def process_request(self, request): print(\'m2.process_request\')
2、注册中间件
MIDDLEWARE_CLASSES = ( \'django.contrib.sessions.middleware.SessionMiddleware\', \'django.middleware.common.CommonMiddleware\', \'django.middleware.csrf.CsrfViewMiddleware\', \'django.contrib.auth.middleware.AuthenticationMiddleware\', \'django.contrib.auth.middleware.SessionAuthenticationMiddleware\', \'django.contrib.messages.middleware.MessageMiddleware\', \'django.middleware.clickjacking.XFrameOptionsMiddleware\', \'wupeiqi.middleware.auth.RequestExeute\', #在合适的位置引入 \'md.middleware.M1\', \'md.middleware.M2\', )
二、 Http请求本质
Django程序:socket服务端
a. 服务端监听IP和端口
c. 接受请求
\\r\\n\\r\\n:请求头和请求体
\\r\\n
&
request.POST
request.GET
d. 响应:
响应头: location:www.oldboyedu.com
响应体
e. 断开连接
浏览器: socket客户端
b. 浏览器发送:
GET请求:
"GET /index.html http1.1\\r\\nUser-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x6..\\r\\n\\r\\nAccept-Encoding:gzip\\r\\n\\r\\n"
POST请求:
"POST /index.html http1.1\\r\\nUser-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x6..\\r\\n\\r\\nAccept-Encoding:gzip\\r\\n\\r\\nuser=cqz&hobby=lihao"
e. 断开连接
COOKIE: 请求头和响应头中存在
三、Django请求的生命周期
wsgi -> 中间件 -> 路由系统 -> 视图函数(ORM,Template,渲染)
- wsgiref
- uwsgi
四、FBV和CBV
1、FBV
FBV(function base views) 就是在视图里使用函数处理请求。
看代码:
urls.py
from django.conf.urls import url, include # from django.contrib import admin from mytest import views urlpatterns = [ # url(r‘^admin/‘, admin.site.urls), url(r‘^index/‘, views.index), ]
views.py
from django.shortcuts import render def index(req): if req.method == ‘POST‘: print(‘method is :‘ + req.method) elif req.method == ‘GET‘: print(‘method is :‘ + req.method) return render(req, ‘index.html‘)
注意此处定义的是函数【def index(req):】
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <form action="" method="post"> <input type="text" name="A" /> <input type="submit" name="b" value="提交" /> </form> </body> </html>
2、CBV
CBV(class base views) 就是在视图里使用类处理请求。
将上述代码中的urls.py 修改为如下:
from mytest import views urlpatterns = [ # url(r‘^index/‘, views.index), url(r‘^index/‘, views.Index.as_view()), ]
注:url(r‘^index/‘, views.Index.as_view()), 是固定用法。
将上述代码中的views.py 修改为如下:
from django.views import View class Index(View): def get(self, req): print(‘method is :‘ + req.method) return render(req, ‘index.html‘) def post(self, req): print(‘method is :‘ + req.method) return render(req, ‘index.html‘)
3、装饰器的使用
from django.utils.decorators import method_decorator
3.1 在get,post方法上
class LoginView(View): def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request): return render(request,\'login.html\') @method_decorator(test) def post(self,request): # request.GET # request.POST # 请求头中的:content-type # request.body user = request.POST.get(\'user\') pwd = request.POST.get(\'pwd\') if user == \'alex\' and pwd == "alex3714": # 生成随机字符串 # 写浏览器cookie: session_id: 随机字符串 # 写到服务端session: # { # "随机字符串": {\'user_info\':\'alex} # } request.session[\'user_info\'] = "alex" return redirect(\'/index.html\') return render(request, \'login.html\')
3.2 在dispatch方法上
class LoginView(View): @method_decorator(test) def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request): return render(request,\'login.html\') def post(self,request): # request.GET # request.POST # 请求头中的:content-type # request.body user = request.POST.get(\'user\') pwd = request.POST.get(\'pwd\') if user == \'alex\' and pwd == "alex3714": # 生成随机字符串 # 写浏览器cookie: session_id: 随机字符串 # 写到服务端session: # { # "随机字符串": {\'user_info\':\'alex} # } request.session[\'user_info\'] = "alex" return redirect(\'/index.html\') return render(request, \'login.html\')
3.3 在类上
@method_decorator(test,name=\'get\') class LoginView(View): def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request): return render(request,\'login.html\') def post(self,request): # request.GET # request.POST # 请求头中的:content-type # request.body user = request.POST.get(\'user\') pwd = request.POST.get(\'pwd\') if user == \'alex\' and pwd == "alex3714": # 生成随机字符串 # 写浏览器cookie: session_id: 随机字符串 # 写到服务端session: # { # "随机字符串": {\'user_info\':\'alex} # } request.session[\'user_info\'] = "alex" return redirect(\'/index.html\') return render(request, \'login.html\')
特殊:CSRF Token只能加到dispatch
from django.views.decorators.csrf import csrf_exempt,csrf_protect class LoginView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request): return render(request,\'login.html\') def post(self,request): # request.GET # request.POST # 请求头中的:content-type # request.body user = request.POST.get(\'user\') pwd = request.POST.get(\'pwd\') if user == \'alex\' and pwd == "alex3714": # 生成随机字符串 # 写浏览器cookie: session_id: 随机字符串 # 写到服务端session: # { # "随机字符串": {\'user_info\':\'alex} # } request.session[\'user_info\'] = "alex" return redirect(\'/index.html\') return render(request, \'login.html\')
以上是关于Django补充——中间件请求的生命周期等的主要内容,如果未能解决你的问题,请参考以下文章
Django框架进阶7 django请求生命周期流程图, django中间件, csrf跨站请求伪造, auth认证模块