<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
CBV
加裝飾器有三種方法,
案例:要求登入(不管get請求還是post請求)後才可以存取
HTML程式碼
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div> <p>Hello Index</p> </div> </body> </html>
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div> <form action="" method="post"> <p>username:<input type="text" name="username"></p> <p>password:<input type="password" name="password"></p> <p><input type="submit" value="提交"></p> </form> </div> </body> </html>
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
工具
中介軟體是 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
中介軟體作用:
中介軟體執行順序:
中介軟體可以定義四個方法:
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 """
自定義中介軟體先執行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是不執行的
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
官網上給的範例:
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
引數。還可以初始化中介軟體的一些全域性狀態。記住兩個注意事項:
上面只定義了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("處理檢視函數錯誤")
使用Django
框架使用django.middleware.csrf.CsrfViewMiddleware
中介軟體,在前端頁面提交操作的時候,會報錯:
Forbidden (403) CSRF verification failed. Request aborted.
解決方法:
如果使用form提交,則在前端頁面里加入:
{% csrf_token %}
如:
<div> <form action="" method="post"> {% csrf_token %} <label>username: <input type="text" name="username"></label> <label>password:<input type="password" name="password"></label> <label><input type="submit" value="提交"></label> </form> </div> 如果是Ajax提交: """一定要匯入jquery""" <body> <div> <label>username: <input type="text" name="username" id="user"></label> <label>password:<input type="password" name="password" id="pwd"></label> <input type="button" value="提交" id="btn"> </div> <script> $('#btn').click(function (){ $.ajax({ url: "", method: "post", data: {username: $('#user').val(), password: $('#pwd').val(), csrfmiddlewaretoken: '{{csrf_token}}'}, success: function (data) { console.log(data) } }) }) </script> </body> # 使用cookie: 使用cookie 則要匯入"""jquery.cookie.min.js""" <script src="https://cdn.bootcdn.net/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> const csrftoken = $.cookie('csrftoken'); 使用: <body> <div> <label>username: <input type="text" name="username" id="user"></label> <label>password:<input type="password" name="password" id="pwd"></label> <input type="button" value="提交" id="btn"> </div> <script> $('#btn').click(function (){ const csrftoken = $.cookie('csrftoken'); $.ajax({ url: "", headers:{'X-CSRFToken': csrftoken}, // 加請求頭。 method: "post", data: {username: $('#user').val(), password: $('#pwd').val()}, success: function (data) { console.log(data) } }) }) </script> </body>
全域性使用csrf區域性函數使用,或全域性不使用,區域性函數使用csrf
from django.views.decorators.csrf import csrf_exempt,csrf_protect # 全域性使用,區域性不使用 @csrf_exempt def xxx() # 全域性不使用(禁用掉),區域性使用 @csrf_protect def yyy()
以上就是Django基礎CBV裝飾器和中介軟體的詳細內容,更多關於Django基礎CBV裝飾器和中介軟體的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45