当前位置: 首页 > 后端技术 > Python

Django笔记29:中间件介绍

时间:2023-03-26 16:54:47 Python

本节介绍Django中间件。关于中间件,官方文档解释说,中间件是一个嵌入在Django系统的请求和响应中的钩子框架,是一个可以全局改变Django的输入/输出的系统。我们可以这样理解,在向Django系统发送请求的过程中,会经过一层处理,然后才会被路由和视图处理。这个处理操作可以是日志记录,登录验证甚至是你想要定义的功能,这个操作就是中间件实现的功能。下面我们通过记录请求ip的功能介绍来介绍中间件的实现过程。以下是本文笔记目录:通过Django请求并返回的过程HttpRequest和HttpResponse介绍中间件实例介绍记录访问IP的功能1.通过Django请求并返回的过程首先,前端发起一个请求,通过web服务器转发到Django系统,进入Django系统后,首先会经过一系列的中间件功能处理。这个中间件将在settings.py中定义。Django系统默认的中间件列表如下:middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickOjacking.XFrame,]我们也可以根据自己的需要定义这些中间件,比如增加新的登录权限,或者日志记录,或者格式化输入参数,或者其他我们想设置的功能。后面会介绍如何设置。在中间件处理的过程中,请求是从上到下顺序处理的。完成此过程后,请求将与URL的路径匹配。如果匹配,则进入对应的views视图函数进行数据处理。views处理完之后,会形成一个response,返回,然后再经过中间件处理,因为中间件的每一层都类似于一种嵌套,所以返回response的时候,从底层重新处理response到达顶点。中间件处理完成后返回给前端。在这整个流程过程中,可以说中间件做了两个操作,一个是进入时处理请求,一个是返回时处理响应。2、HttpRequest和HttpResponse介绍先来看一个视图函数:deftime_view(request):now=datetime.datetime.now()html="

now:%s

abc\nabc"%nowreturnHttpResponse(html)当Django收到一个请求时,系统会创建一个HttpRequest对象,它是上面视图函数中的入参。请求处理完数据后,系统会返回一个HttpResponse对象,也就是我们返回的内容。在一个HttpRequest对象中,会包含请求到来时的请求路径、参数、请求方法、cookie等数据,我们在请求时可以根据需要访问。返回的HttpResponse中可以是html页面,也可以是json格式的数据。内容可以自定义,只要前端能做相应的处理即可。3.中间件示例介绍接下来我们定义一个中间件,结构如下:#huter/middleware.pyclassSimpleMiddleware:def__init__(self,get_response):self.get_response=get_responsedef__call__(self,request):#inSomeoperations可以在请求进入视图函数之前执行,forrequestprint(request.path)response=self.get_response(request)#处理完请求后,可以执行一些操作,forresponse#log_response_info()returnresponse然后我们在stings.py中引入这个中间件,我们把它放在MIDDLEWARE列表的最下面,表示这个中间件会在其他中间件处理完请求之后再处理:MIDDLEWARE=['django.middleware.security.SecurityMiddleware','姜戈。contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware','hunter.middleware.TestMiddleware',]在SimpleMiddleware类中会自动调用__call__()函数,在这行函数之前有一行,response=self.get_response(request),可以处理请求的request,包括我们前面提到的各种函数,比如日志,登录验证,参数格式化等,在这行之后functions,得到了response,这是视图函数返回的HttpResponse,我们可以在这里处理它的response.status_code状态码和response.content。比如前面的time_view函数返回的内容是一个JsonResponse:returnJsonResponse({"code":0})那么这里我们就可以获取并处理这个HttpResponse:def__call__(self,request):response=self.get_response(request)content=json.loads(response.content)content["msg"]="success"response.content=json.dumps(content)returnresponse这里只是一个例子,因为并不是所有的HttpResponse都是json格式的数据,所以你可能需要添加一个尝试除了处理。还有一个我之前做过的功能是的,就是在headers中添加一个特定的字符串,表示它是我们系统专有的,用于前端判断。这个很简单,就是在response的headers参数中添加一个键值对:response.headers['system']='hunter'以上就是最简单的中间件处理方法process_view除了调用函数,还有一个process_view()函数。这个函数在Django系统调用views视图函数之前被调用,它的返回值为None或者如果一个HttpResponse为None,那么系统就会调用视图函数。如果是HttpResponse作为返回值,说明系统已经处理了这里的请求,不需要再去views视图函数,直接返回。我们用下面的例子来说明这个函数的作用。4.记录访问ip功能的实现假设我们需要禁止某个或者某个ip列表的请求访问我们的系统当然这个操作可以在web服务器部分进行拦截。这里只是一个例子。然后我们设置一个process_view的函数,在真正执行视图函数之前(也就是url匹配上的视图函数),取出请求访问的ip,然后进行判断。如果在禁止列表中,则直接返回禁止访问的页面。类TestMiddleware:def__init__(self,get_response):self.get_response=get_responsedef__call__(self,request):response=self.get_response(request)返回响应defprocess_view(self,request,view_func,*view_args,**sview_kwar:EXCLUDE_IPS=['192.168.1.54']if'HTTP_X_FORWARDED_FOR'inrequest.META:ip=request.META['HTTP_X_FORWARDED_FOR']else:ip=request.META['REMOTE_ADDR']ifipinEXCLUDE_IPS:returnHttpResponse('

Youripisbanned

')returnNone在这里,我们得到请求的ip地址并与被禁止的进行比较我们定义的ip列表,如果在banned列表中,直接返回HttpResponse,不继续请求,否则我们的服务会返回None,系统收到None后继续处理。