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
