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