網站首頁 編程語言 正文
1. CBV加裝飾器
CBV
加裝飾器有三種方法,
案例:要求登錄(不管get請求還是post請求)后才可以訪問
HTML代碼
index.html
Title Hello Index
login.html
Title
views.py
# CBV加裝飾器方法一: from django.shortcuts import render, HttpResponse, redirect from django.views import View from django.utils.decorators import method_decorator # django提交加裝飾器方法 # Create your views here. # 裝飾器 def login_auth(func): def inner(request, *args, **kwargs): if request.session.get("is_login"): res = func(*args, **kwargs) return res else: return redirect('/login/') return inner class Index(View): # 方法一在每個需要驗證的地方都加上裝飾器 @method_decorator(login_auth) def get(self, request): print("get 請求") return render(request, "index.html") # 個需要驗證的地方加上裝飾器 @method_decorator(login_auth) def post(self, request): print("post 請求") return HttpResponse("post") def login(request): if request.method == "POST": name = request.POST.get("username") password = request.POST.get("password") if name == "hans" and password == "123": request.session['is_login'] = True print("登錄成功") return render(request, "login.html") # CBV加裝飾器方法二: from django.shortcuts import render, HttpResponse, redirect from django.views import View from django.utils.decorators import method_decorator # Create your views here. # 裝飾器 def login_auth(func): def inner(request, *args, **kwargs): if request.session.get("is_login"): res = func(*args, **kwargs) return res else: return redirect('/login/') return inner # 方法二 在類的上面加上,name為具體要加的函數 @method_decorator(login_auth, name='post') @method_decorator(login_auth, name='get') class Index(View): def get(self, request): print("get 請求") return render(request, "index.html") def post(self, request): print("post 請求") return HttpResponse("post") def login(request): if request.method == "POST": name = request.POST.get("username") password = request.POST.get("password") if name == "hans" and password == "123": request.session['is_login'] = True print("登錄成功") return render(request, "login.html") # CBV加裝飾器方法三: from django.shortcuts import render, HttpResponse, redirect from django.views import View from django.utils.decorators import method_decorator # Create your views here. # 裝飾器 def login_auth(func): def inner(request, *args, **kwargs): if request.session.get("is_login"): res = func(*args, **kwargs) return res else: return redirect('/login/') return inner class Index(View): #方法三 使用dispatch給所有的方法添加裝飾器 @method_decorator(login_auth) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) def get(self, request): print("get 請求") return render(request, "index.html") def post(self, request): print("post 請求") return HttpResponse("post") def login(request): if request.method == "POST": name = request.POST.get("username") password = request.POST.get("password") if name == "hans" and password == "123": request.session['is_login'] = True print("登錄成功") return render(request, "login.html")
urls.py
from django.contrib import admin from django.urls import path from wrapperMidd import views urlpatterns = [ path('admin/', admin.site.urls), path('index/', views.Index.as_view()), path('login/', views.login), ]
訪問地址:http://127.0.0.1:8000/index
get
的請求使用POSTMAN
工具
2. Django中間件
2.1 Django中間件介紹
中間件是?Django?
請求/響應處理的鉤子框架。它是一個輕量級的、低級的“插件”系統,用于全局改變?Django?
的輸入或輸出。
每個中間件組件負責做一些特定的功能,Django
中自帶了七個中間件
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', # 安全中間件,為請求/響應周期提供了若干安全增強功能。每一項都可以通過設置獨立地啟用或禁用。 'django.contrib.sessions.middleware.SessionMiddleware', # 啟用會話支持 'django.middleware.common.CommonMiddleware', # “通用”中間件 'django.middleware.csrf.CsrfViewMiddleware', # CSRF 保護中間件,通過在 POST 表單中添加隱藏的表單字段,并檢查請求的正確值,增加對跨站點偽造請求的保護。 'django.contrib.auth.middleware.AuthenticationMiddleware', # 驗證中間件,將代表當前登錄的用戶的 user 屬性添加到每個傳入的 HttpRequest 對象中 'django.contrib.messages.middleware.MessageMiddleware', # 消息中間件,啟用基于 cookie 和會話的消息支持 'django.middleware.clickjacking.XFrameOptionsMiddleware', # X-Frame-Options 中間件,簡單的 通過 X-Frame-Options 頭的點擊劫持保護。 ]
中間件(Middleware
)在整個Django
的request/response
處理機制中的角色如下所示:
HttpRequest -> Middleware(request) -> View -> Middleware(response) -> HttpResponse
中間件常用于權限校驗、限制用戶請求、打印日志、改變輸出內容等多種應用場景.而且中間件對Django的輸入或輸出的改變是全局的。
Django
?中間件作用:
- 修改請求,即傳送到 view 中的 HttpRequest 對象。
- 修改響應,即 view 返回的 HttpResponse 對象。
中間件執行順序:
2.2 自定義中間件
中間件可以定義四個方法:
process_request(self,request)
process_view(self, request, view_func, view_args, view_kwargs)
process_exception(self, request, exception)
process_response(self, request, response)
主要為process_request
和process_response
在應用目錄下新建一個 py 文件,名字自定義。
在應用目錄下創建myMiddle.py myMiddle.py: from django.utils.deprecation import MiddlewareMixin class myMinddle(MiddlewareMixin): def process_request(self, request): # 在視圖之前執行 print("這是自定義中間件 請求1") def process_response(self,request, response): #在視圖之后執行 print("這是自定義中間件 響應1") return response
把自定義的中間件注冊到setting.py
的?MIDDLEWARE
里面:
setting.py: MIDDLEWARE = [ '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', 'wrapperMidd.myMinddle.myMinddle', # 自定義中間件 ]
測試:
views.py: from django.shortcuts import render, HttpResponse, redirect def testMinddle(request): print("testMinddle") return HttpResponse("TEST") urls.py: from django.contrib import admin from django.urls import path from appName import views urlpatterns = [ path('admin/', admin.site.urls), path('testMinddle/', views.testMinddle), ] # 訪問:http://127.0.0.1:8000/testMinddle/ # 結果: """ 這是自定義中間件 請求1 testMinddle 這是自定義中間件 響應1 """
增加兩個自定義中間件,執行過程:
myMiddle.py: from django.utils.deprecation import MiddlewareMixin class myMinddle(MiddlewareMixin): def process_request(self, request): print("這是自定義中間件 請求1") def process_response(self,request, response): print("這是自定義中間件 響應1") return response class myMinddle2(MiddlewareMixin): def process_request(self, request): print("這是自定義中間件 請求2") def process_response(self,request, response): print("這是自定義中間件 響應2") return response setting.py: MIDDLEWARE = [ ...... 'wrapperMidd.myMinddle.myMinddle', 'wrapperMidd.myMinddle.myMinddle2', ] # 訪問:http://127.0.0.1:8000/testMinddle/ # 結果 """ 這是自定義中間件 請求1 這是自定義中間件 請求2 testMinddle 這是自定義中間件 響應2 這是自定義中間件 響應1 """
如果在第一個中間件直接返回,執行順序如果:
myMiddle.py: from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class myMinddle(MiddlewareMixin): def process_request(self, request): print("這是自定義中間件 請求1") return HttpResponse("request") """在這里直接返回""" def process_response(self,request, response): print("這是自定義中間件 響應1") return response class myMinddle2(MiddlewareMixin): def process_request(self, request): print("這是自定義中間件 請求2") def process_response(self,request, response): print("這是自定義中間件 響應2") return response # 訪問:http://127.0.0.1:8000/testMinddle/ # 結果: 網頁上顯示:request 后臺顯示: """ 這是自定義中間件 請求1 這是自定義中間件 響應1 """
2.3 自定義中間件總結
自定義中間件先執行process_request
再執行views.py
里的視圖函數,最后再執行process_response
,而且process_response
函數必須要返回?return response
如果有多個自定義中間件,則執行順序按settings.py
里自上而下執行,寫在上面的先執行。執行順序
自定義中間件1 process_request--->自定義中間件2 process_request-->視圖函數-->自定義中間件2 process_response -->自定義中間件1 process_response
如果自定義中間件的process_request
里有return
返回,而這個中間件還是在上面,則它會執行自己定義的process_request
和process_response
,則視圖函數和其他的中間件都不執行
如果自定義中間件的process_request
里有return
返回,而這個中間件上面還有其他的中間件,則會自上而下執行,執行到自定義中間件的process_request
后就會執行process_response
,則視圖函數和它下面的中間件都不執行
MIDDLEWARE = [ ...其他中間件... '自定義中間件1', '自定義中間件2', # 自定義中間件2里使用return直接返回 '自定義中間件3', ] 執行順序: """ 其他中間件 process_request --> 自定義中間件1 process_request --> 自定義中間件2 process_request --> 自定義中間件2 process_response --> 自定義中間件1 process_response -->其他中間件 process_response """ 視圖函數和自定義中間件3是不執行的
2.4 其他中間件函數
process_view
process_view在process_request之后,路由轉發到視圖,執行視圖之前執行。
process_view() 只在 Django 調用視圖前被調用。它應該返回 None 或 HttpResponse 對象。如果它返回 None ,Django 將繼續處理這個請求,執行任何其他的 process_view() ,然后執行相應的視圖。如果它返回 HttpResponse 對象,Django 不會去影響調用相應的視圖;它會將響應中間件應用到 HttpResponse 并返回結果。
函數定義:
process_view(request, view_func, view_args, view_kwargs)
request 是一個 HttpRequest 對象。
view_func 是一個 Django 將要使用的 Python 函數。(這是一個真實的函數對象,不是函數的名稱);view_args 是一個用來傳遞給視圖的位置參數列表,;
view_kwargs 是一個用來傳遞給視圖的關鍵字參數字典。
view_args 和 view_kwargs 都不包含第一個視圖參數 ( request )。
process_exception
視圖執行中發生異常時執行。
當視圖引發異常時,Django 會調用 process_exception()。process_exception() 應該返回 None 或 HttpResponse 對象。如果它返回一個 HttpResponse 對象,模板響應和響應中間件將被應用且會將結果響應返回瀏覽器。否則,就會開始默認異常處理( default exception handling )。
再次,中間件在響應階段會按照相反的順序運行,其中包括 process_exception 。如果異常中間件返回一個響應,那么中間件之上的中間件類的 process_exception 方法根本不會被調用。
函數定義:
process_exception(request, exception)
request 是一個 HttpRequest 對象。 exception 是一個由視圖函數引發的 Exception 對象。
process_template_response
視圖函數剛執行完畢,process_response之前執行。
process_template_response() 在視圖被完全執行后調用,如果響應實例有 render() 方法,表明它是一個 TemplateResponse 或等效對象。
它必須返回一個實現了 render 方法的響應對象。它可以通過改變``response.template_name`` 和 response.context_data 來改變給定的 response ,或者它可以創建和返回全新的 TemplateResponse 或等效對象。
不需要顯式地渲染響應——一旦所有模板中間件被調用,響應會被自動渲染。
中間件會在響應階段按照相反的順序運行,其中包括 process_template_response() 。
函數定義:
process_template_response(request, response)
request 是一個 HttpRequest 對象。
response 是 TemplateResponse 對象(或者等效對象),它通過 Django 視圖或中間件返回。
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class myMinddle(MiddlewareMixin): def process_request(self, request): print("這是自定義中間件 請求1") def process_response(self,request, response): print("這是自定義中間件 響應1") return response def process_view(self,request, view_func, view_args, view_kwargs): print("視圖函數之前執行") def process_exception(self,request,exception): print("處理視圖函數")
訪問http://127.0.0.1:8000/testMinddle/
結果:
這是自定義中間件 請求1
視圖函數之前執行
testMinddle
這是自定義中間件 響應1
視圖函數出錯示例:
這是自定義中間件 請求1
視圖函數之前執行
testMinddle
處理視圖函數錯誤
這是自定義中間件 響應1
2.5新版本中間件寫法
官網上給的示例:
class SimpleMiddleware: def __init__(self, get_response): self.get_response = get_response # 配置和初始化 def __call__(self, request): # 在這里編寫視圖和后面的中間件被調用之前需要執行的代碼,即process_request() response = self.get_response(request) # 在這里編寫視圖調用后需要執行的代碼,即process_response() return response
案例:
使用官網上的寫法不用繼承 MiddlewareMixin
class SimpleMiddleware: def __init__(self, get_response): self.get_response = get_response # One-time configuration and initialization. def __call__(self, request): # Code to be executed for each request before # the view (and later middleware) are called. print("這是自定義中間件 SimpleMiddleware的請求") response = self.get_response(request) # Code to be executed for each request/response after # the view is called. print("這是自定義中間件 SimpleMiddleware的響應") return response
執行結果:
這是自定義中間件 SimpleMiddleware的請求
testMinddle
這是自定義中間件 SimpleMiddleware的響應
注意
__init__(get_response)
中間件必須接受?get_response
?參數。還可以初始化中間件的一些全局狀態。記住兩個注意事項:
- Django僅用??參數初始化您的中間件,因此不能定義?__init__()?,因為需要其他參數。
- 與每次請求都會調用?__call__()?方法不同,當 Web 服務器啟動后,__init__()?只被調用一次
上面只定義了process_request
和process_response
?其中process_view
和process_exception
還是要寫。
class SimpleMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): print("這是自定義中間件 SimpleMiddleware的請求") response = self.get_response(request) print("這是自定義中間件 SimpleMiddleware的響應") return response def process_view(self,request, view_func, view_args, view_kwargs): print("視圖函數之前執行") def process_exception(self,request,exception): print("處理視圖函數錯誤")
3.Csrf中間件
使用Django
框架使用django.middleware.csrf.CsrfViewMiddleware
中間件,在前端頁面提交操作的時候,會報錯:
Forbidden (403) CSRF verification failed. Request aborted.
解決方法:
如果使用form提交,則在前端頁面里加入:
? ? {% csrf_token %}
如:
如果是Ajax提交: """一定要導入jquery"""# 使用cookie: 使用cookie 則要導入"""jquery.cookie.min.js""" const csrftoken = $.cookie('csrftoken'); 使用:
全局使用csrf局部函數使用,或全局不使用,局部函數使用csrf
from django.views.decorators.csrf import csrf_exempt,csrf_protect # 全局使用,局部不使用 @csrf_exempt def xxx() # 全局不使用(禁用掉),局部使用 @csrf_protect def yyy()
原文鏈接:https://www.cnblogs.com/hans-python/p/16037470.html
相關推薦
- 2023-05-22 python使用ctypes調用第三方庫時出現undefined?symbol錯誤詳解_python
- 2024-01-16 where語句后跟case語句
- 2023-12-23 css設置文字超出顯示...
- 2022-02-22 el-step中多個步驟中的表單一起提交
- 2022-05-24 C#多線程TPL模式下使用HttpClient_C#教程
- 2022-12-21 Swift使用enum抹平數組元素差異實例詳解_Swift
- 2022-08-16 C#在MEF框架中實現延遲加載部件_C#教程
- 2022-11-14 Python中__init__.py文件的作用_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支