django学习第十三天--自定义中间件(django消息队列中间件)

网友投稿 233 2022-08-29


django学习第十三天--自定义中间件(django消息队列中间件)

jquery操作cookie

下载地址

type="text/javascript" src="js/jquery.min.js">

cookie操作

设置值: $.cookie('the_cookie','the_value'); #设置7天有效期 $.cookie('the_cookie','the_value',{expires:7}); 读取 $.cookie('the_cookie'); #通过键来取值 删除cookie $.cookie('the_cookie',null); #通过传递null作为cookie的值即可

中间件

配置文件

项目主目录中的配置文件是django留给开发者使用的用户级别配置文件 实际上django有一个自己的默认全局配置文件 那么他们的关系如下 #django默认配置 from django.conf import global_settings #用户级别配置 from django_middleware import settinigs from django.conf import settings #中间人 #比如需要引入配置中的某个配置项settings.APPEND_SLASH,那么这样的引入的查找顺序是这样的,先去用户级别settings.py文件中找这个配置,如果没有找到,那么再去global_settings中去找默认配置

django请求生命周期

中间件用来对请求和响应做一些统一加工和处理的,比如对所有请求中的post请求做一个csrftoken认证,就用到了我们的'django.middleware.csrf.CsrfViewMiddleware',后面视图中能够使用request.session做一个session相关操作,这个request.session的功能就是在这个中间件中加工好的'django.contrib.sessions.middleware.SessionMiddleware'

自定义中间件

登录认证、权限认证、频率访问限制、请求数据统计等等...自定义中间的步骤

1.应用文件夹下面创建一个文件夹,名字随便起,比如叫作mymiddleware 2.在mymiddleware文件夹下面创建一个py文件,名称随意,比如叫做middlewares.py 3.在middlewares.py文件中写上如下内容 from django.utils.deprecation import MiddlewareMixin class LoginAuth(MiddlewareMixin): def process_request(self,request): print('xxx') 4.settings.py配置文件中写上如下内容 MIDDLEWARE = [ .... '应用名.中间文件夹.中间文件.类' 'app01.mymiddleware.middlewares.LoginAuth', #配置中间件类,告诉django,我写的这个自定义中间件,你帮我使用上,一般都是放到最后,不然上面几个中间件的相关功能就没办法使用上了。 #如果中间件功能不想用了,就注释掉它就行了。 #以上几步搞定后,所有请求都会触发我们的中间件类中的process_request方法。 ]

登录认证中间示例

中间件代码如下 #登录认证中间件 class LoginAuth(MiddlewareMixin): #/login/登录请求,应该正常放行,让他能获得login.html页面 #添加一个白名单,这样首页登录就不需要登录认证 white_list = ['/login/',] def process_request(self,request): print('请求来啦!!!') #获取当前请求路径:request.path /login/ #如果当前请求路径在白名单里面,我们不进行登录认证 if not request.path in self.white_list: is_login = request.session.get('is_login') #True if not is_login: return redirect('/login/') #视图代码 def login(request): if request.method == 'GET': return render(request,'login.html') else: #print('xxxxxx') uname = request.POST.get('username') if uname == 'root': request.session['is_login'] = True return redirect('/home/')#告诉浏览器向/home/发送get请求获取页面 else: return redirect('/login/') def home(request): print('home') return render(request,'home.html') def index(request): print('index') return render(request,'index.html') #执行步骤:如判断用户访问home页面,是否已经登录过了 第一次请求的时候,先是走的中间件process_request,login路径,在白名单里面,所以就不会走下面的判断, 实际后面会有个return None,就表示是正常返回,可以省略不用写,然后再去执行视图逻辑,获取到login页面,get请求获取login页面。 第二次填写数据发送post请求,又会走一遍process_request,正常返回后再去执行视图逻辑,后台获取发送来的数据, 设置session,然后重定向到home页面,重定向的时候又会走了一遍process_request,然后中间件会判断这个重定向的路径,最后再执行视图逻辑。 下次想直接访问home页面的时候,先是发送/home/请求,先走中间件process_request,判断当前的路径是不是在白名单里, 显然不在,然后执行下面的逻辑代码,获取到session中的键值对,如获取到了,return None,那么就会执行视图里面的逻辑,就直接执行home函数。 如没有获取到,那么直接在中间件代码里面直接就重定向到login页面。

中间件的五个方法

整个中间件的执行顺序

process_request从上到下,process_response从下到上

五个方法:process_request和process_response这个两个是重点

process_request(self,request) #请求 process_view(self,request,view_func,view_args,view_kwargs)#视图 process_template_response(self,request,response)#模板 process_exception(self,request,exception) #错误 process_response(self,request,response) #响应

每个方法的执行流程

1.process_request

class Md1(MiddlewareMixin): def process_request(self,request): print('MD1--process_request') #当process_request返回时None,可以默认不写,那么才会继续执行后面的中间件的process_request,如果你是最后一个中间件,并且你返回的是None,那么逻辑会继续执行到我们的url路由控制器 #但是当process_request里面return的是一个HttpResponse对象,那么后面的中间件的process_request将不再执行,也不会走到url路由控制器 #return HttpResponse('中间件md1的逻辑,没有通过!!!') class Md2(MiddlewareMixin): def process_request(self,request): print('MD1--process_request') views.py代码 def home(request): print('home') return render(request,'home.html') 执行流程--中间件正常return None的情况: MD1--process_request MD2--process_request home 执行流程--中间件Md1中响应回复对象的情况: MD1--process_request 因为Md1中return的是响应对象,所以就不会再向下执行了,同时也不会去执行逻辑代码。

2.process_response

class Md1(MiddlewareMixin): def process_request(self,request): print('MD1--process_request') def process_response(self,request,response): :param request: 当前请求对象 :param response: 视图函数的响应对象 :return: print('Md1--响应') #可以对响应内容做统一处理,如加响应头 response['xx'] = 'oo' print(response.content) #获取响应回复内容 #b'ok' #注意,如果你写了process_response方法,那么这个方法必须return response return response class Md2(MiddlewareMixin): def process_request(self,request,response): print('MD2--process_request') def process_response(self,request,response): print('MD2--响应') # if response.content != b'ok': #如果process_response方法里面return了一个HttpResponse对象,那么这个对象会覆盖视图返回来的HttpResponse对象 #return HttpResponse('响应不OK!!!') return response views.py文件 def home(request): print('home') return render(request,'home.html') #return HttpResponse('我是home响应') 执行流程 正常执行: MD1--process_request #中间件请求从上至下 MD2--process_request home #请求结束会后执行视图逻辑 MD2--process_response #中间响应从下至上 MD1--process_response 执行流程 中间件HttpResponse响应覆盖视图返回来的Httpresponse对象: MD1--process_request #中间件请求从上至下 MD2--process_request home #执行视图逻辑,响应我是home响应 MD2--process_response #中间件响应从下至上,覆盖视图响应对象响应不OK!!! MD1--process_response

注意事项

当中间件1的process_request方法return的是一个HttpResponse,那么会执行中间件1的process_response方法,不会去执行中间件2的方法了

3.process_view(self,request,view_func,view_args,view_kwargs)

from django.shortcuts import render,redirect,HttpResponse from django.utils.deprecation import MiddlewareMix class Md1(MiddlewareMixin): def process_request(self,request): print('MD1--process_request') def process_response(self,request,response): print('MD1--process_response') return response def process_view(self,request,view_func,view_args,view_kwargs): print('MD1--process_view') class Md2(MiddlewareMixin): def process_request(self,request): print('MD2--process_request') def process_response(self,request,response): :param request: :param view_func: 此次请求要执行的视图函数对象 :param view_args: 要函数的参数 :param view_kwargs: 要函数的参数 :return: print('MD2--process_response') return response def process_view(self,request,view_func,view_args,view_kwargs): print('MD2--process_view') 执行流程: MD1--process_request #中间件请求从上至下 MD2--process_request MD1--process_view #中间件视图从上至下 MD2--process_view 中间件2执行函数名称 home home #逻辑视图 MD2--process_response #中间件响应 从下至上 MD1--process_response

当视图函数出现错误或者异常时,自动触发的方法,能够捕获视图出现的错误,进行一些错误的统一处理 from django.shortcuts import render,redirect,HttpResponse from django.utils.deprecation import MiddlewareMixin class Md1(MiddlewareMixin): def process_request(self,request): print('MD1--process_request') def process_response(self,request,response): print('MD1--process_response') return response def process_view(self,request,view_func,view_args,view_kwargs): print('MD1--process_view') def process_exception(self,request,exception): print('MD1--process_exception') class Md2(MiddlewareMixin): def process_request(self,request): print('MD2--process_request') def process_response(self,request,response): print('MD2--process_response') return response def process_view(self,request,view_func,view_args,view_kwargs): print('MD2--process_view') def process_exception(self,request,exception): from django.core.exceptions import PermissionDenied # print('>>>>>>', exception, type(exception)) # if isinstance(exception,PermissionDenied): # return HttpResponse('权限不够!!!!!') #>>>>>> 权限不够 # >>>>>> 出错啦!!! print('MD2--process_exception') views.py代码 from django.core.exceptions import PermissionDenied #为了演示错误 def home(request): print('home') raise PermissionDenied('权限不够') return render(request,'home.html') 执行流程: MD1--process_request #中间件请求从上至下 MD2--process_request MD1--process_view #中间件视图从上至下 MD2--process_view home #逻辑视图 MD2--process_exception #中间件错误从下至上 MD1--process_exception MD2--process_response #中间件响应从下至上 MD1--process_response

from django.shortcuts import render,redirect,HttpResponse from django.utils.deprecation import MiddlewareMixin class Md1(MiddlewareMixin): def process_request(self,request): print('MD1--process_request') def process_response(self,request,response): print('MD1--process_response') return response def process_view(self,request,view_func,view_args,view_kwargs): print('MD1--process_view') def process_exception(self,request,exception): print('MD1--process_view') def process_template_response(self,request,response): print('MD1--process_template_response') return response class Md2(MiddlewareMixin): def process_request(self,request): print('MD2--process_requeust') def process_response(self,request,response): print('MD2--process_response') def process_view(self,request,view_func,view_args,view_kwargs): print('MD2--process_view') def process_exception(self,request,exception): print('MD2--process_exception') def process_template_response(self,request,response): print('MD2--process_template_response') return response views.py代码 def home(request): print('home') def render(): print('你好render') return HttpResponse('你好response') ret = HttpResponse('ojbk') #必须给HttpResponse对象封装一个render属性等于一个render函数,才能触发中间件里面的process_template_response方法 ret.render = render return ret 执行流程: MD1--process_request #中间件请求从上至下 MD2--process_request MD1--process_view #中间件视图从上至下 MD2--process_view home #视图逻辑 MD2--process_template_response #中间件模板 从下至上 MD1--process_template_response 你好render #视图逻辑里面的render()函数中响应对象 MD2--process_response #中间件响应 从下至上 MD1--process_response

总结下中间件执行流程

请求到达中间件之后,先按照正序执行每个注册中间件的process_reques方法,process_request方法返回的值是None,就依次执行,如果返回的值是HttpResponse对象,不再执行后面的process_request方法,而是执行当前对应中间件的process_response方法,将HttpResponse对象返回给浏览器。也就是说:如果MIDDLEWARE中注册了6个中间件,执行过程中,第3个中间件返回了一个HttpResponse对象,那么第4,5,6中间件的process_request和process_response方法都不执行,顺序执行3,2,1中间件的process_response方法。

process_request方法都执行完后,匹配路由,找到要执行的视图函数,先不执行视图函数,先执行中间件中的process_view方法,process_view方法返回None,继续按顺序执行,所有process_view方法执行完后执行视图函数。加入中间件3 的process_view方法返回了HttpResponse对象,则4,5,6的process_view以及视图函数都不执行,直接从最后一个中间件,也就是中间件6的process_response方法开始倒序执行。

url路由系统补充---include路由分发和命名空间 namespace

1.创建app

python manage.py startapp app01

2.配置app,在settings.py文件中

INSTALLED_APPS = [ ... 'app02', ]

路由分发步骤

1.在项目主目录下的urls.py(以后我们称之为总路由)文件中,写上如下内容

from django.conf.urls import url,inclue from django.contrib import admin #路由分发功能 urlpatterns = [ url(r'^admin/',admin.site.urls), url(r'^app01/',include('app01.urls')),#include参数格式'应用名称.urls' url(r'^app02/',include('appo2.urls')), #/app01/index/ 先在总路由中匹配前面的路径,然后匹配到了,拿剩下的index/,去app01应用下面的urls.py文件进行路径匹配 ]

2.在每个应用文件夹下面创建一个ursl.py文件,里面内容

from django.conf.urls import url,include from app01 import views urlpatterns = [ url(r'^index/',views.index), ]

问题,当两个应用中的url的别名相同了,使用反向解析的时候该怎么解决

app01的urls.py from django.conf.urls import url,include from app01 import views urlpatterns = [ url(r'^index/',views.index), url(r'^home/',views.home,name='home'), ] app02下的urls.py from django.conf.urls import url,include from app02 import views urlpatterns = [ url(r'^index/',views.index), url(r'^home/',views.home,name='home'), ] app01的views.py文件进行别名解析 def index(request): print('app01>>>',reverse('home')) return HttpResponse('app01-index') app02的views.py文件进行别名解析 def index(request): print('app02>>>',reverse('home')) return HttpResponse('app02-index') 以上执行完后,发现别名冲突,导致反向解析出错了

解决办法,用命名空间

总路由写法 from django.conf.urls import url,include from django.contrib import admin #路由分发 urlpatterns = [ url(r'^app01/',include('app01.urls',namespace='app01')), url(r'^app02/',include('app02.urls',namespace='app02')), ] app01视图写法 def index(request): print('app01>>>',reverse('app01:home')) return HttpResponse('app01-index') app02视图写法 def index(request): print('app02>>',reverse('app02:home')) return HttpResponse('app02-index') 模板中使用 {% url 'app01:home' %}

路由分发如何设置首页

如果我们想通过输入 url(r'^$', views.index),#以空开头,还要以空结尾,写在项目的urls.py文件里面就是项目的首页,写在应用文件夹里面的urls.py文件中,那就是app01的首页

整个完整请求-中间件-后台逻辑处理的过程

-------------------------------------------

个性签名:代码过万,键盘敲烂!!!

如果觉得这篇文章对你有小小的帮助的话,记得“推荐”哦,博主在此感谢!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:django学习第十二天--ajax请求和csrftoken认证的三种方式(django csrftoken验证)
下一篇:django学习第十一天---django操作cookie和session(django session,cookie三者区别)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~