django 中间件
中间件是 Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。
- call(self, request), response = self.get_response(request)获得的是此次要响应给客户端的响应,前后的代码,在客户端,发起请求后,接收到响应前各执行一次。
- 在 response = self.get_response(request)之前的代码段将在客户端,发起请求后,路由匹配前执行。
- 在response = self.get_response(request)之后的代码段将在向客户端响应请求前执行
- process_view(request, view_func, *view_args, **view_kwargs),在url匹配后视图函数处理前调用,如果return None, 那么,调用完后执行url匹配后的视图函数
- def process_exception(request, exception, *args),视图函数执行失败执行此函数
创建工程和应用
- django-admin startproject mySite
- python manage.py startapp frequencylimit
- python mange.py startapp index
- 在 frequencylimit 下新建 frequencylimitmiddleware.py
在 frequencylimit / frequencylimitmiddleware.py 下编写中间件类
from django.http import HttpResponse
# Create your views here.
class SimpleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
print("中间件初始化,__init__")
def __call__(self, request):
# Code to be executed for each request before
# the view (and later middleware) are called.
print("经过下一个中间件之前,__call__")
# 获得 process_view 返回的response 或 视图返回response
response = self.get_response(request)
# Code to be executed for each request/response after
# the view is called.
print("request.META['REMOTE_ADDR']", request.META["REMOTE_ADDR"])
print("访问完视图,__call__")
# print(response.__dict__)
# content = response.__dict__['_container'][0].decode(encoding="utf8")
# print("content:",content)
return response
# 如果return None,就访问视图 view_func(请求对应的后台处理程序)
# 如果return HttpResope对象,那么就不会执行后台相应的程序
def process_view(request, view_func, *view_args, **view_kwargs):
print("访问视图前:process_view")
# return HttpResponse("你还没访问到视图")
def process_exception(request, exception, *args):
print("服务器出错了....",*args)
return HttpResponse("服务器出错了....%")
在index / view.py 编写视图
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
def index(request):
print("执行 index_views")
raise KeyError
return render(request, "index.html", {"content": "ok"})
配置路由
from django.contrib import admin
from django.urls import path
from index.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path("index/", index),
]
设置 settings
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 注册应用
'index',
'frequencylimit',
]
MIDDLEWARE = [
# 自定义的中间件
# 放在最上面,客户端的访问requst,按顺序从前往后经过中件间的检查,最后访问后台得到response,
# reponse按顺序从后往前过中件间的审视最后响应给客户端
"frequencylimit.frequencylimitmiddleware.SimpleMiddleware",
'django.middleware.security.SecurityMiddleware',
'django.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',
]
执行结果
System check identified no issues (0 silenced).
March 07, 2019 - 10:22:17
Django version 2.1.7, using settings 'webSite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
中间件初始化,__init__
经过下一个中间件之前,__call__
访问视图前:process_view
执行 index_views
服务器出错了....
访问完视图,__call__
[07/Mar/2019 10:22:24] "GET /index/ HTTP/1.1" 200 23