django如何通過類視圖使用裝飾器
需求:當(dāng)我們想禁止ip黑名單訪問我們的某些頁面時(shí),例如注冊(cè)頁面。應(yīng)該怎么操作呢?
解決方案:這時(shí)候我們可以設(shè)計(jì)一個(gè)裝飾器,過濾ip黑名單。
裝飾器的寫法如下:
from functools import wraps def ban_ip(func): @wraps(func) def wrapper(request,*args,**kwargs): IP = request.META.get("REMOTE_ADDR") if IP in ["127.0.0.1"]: # 可以添加ip黑名單到列表里 return HttpResponse("禁止訪問") return func return wrapper
如果不是類視圖,可以這樣使用:
@ban_ip def get_register(request): return render(request,"注冊(cè)頁面.html") def post_resiger(request): name = request.POST.get("name") password = request.POST.get("password") print(name) print(password) return HttpResponse("注冊(cè)成功")
這樣就可以達(dá)到一個(gè)效果。如果ip在黑名單里,那么訪問注冊(cè)頁面時(shí)會(huì)彈出“禁止訪問”。
需求:但是,問題來了,當(dāng)我們使用類視圖時(shí),定義視圖函數(shù)時(shí)還有一個(gè)self參數(shù)。因?yàn)檠b飾器沒有傳這個(gè)參,所以會(huì)報(bào)錯(cuò)。應(yīng)該怎么辦呢?
解決辦法:
(1)給類視圖中特定的方法
class register(View): @method_decorator(ban_ip) def get(self,request): return render(request,"注冊(cè)頁面.html") def post(self,request): name = request.POST.get("name") password = request.POST.get("password") print(name) print(password) return HttpResponse("注冊(cè)成功")
解讀:
- 注意:針對(duì)函數(shù)定義的裝飾器,不能直接應(yīng)用到類視圖的方法中,因?yàn)樯倭艘粋€(gè)self參數(shù)
- 解決:可以使用method_decorator裝飾器,為函數(shù)裝飾器補(bǔ)充第一個(gè)self參數(shù),使它可以應(yīng)用到類的方法中。
(2)給所有類視圖的所有方法應(yīng)用裝飾器
類視圖的實(shí)現(xiàn)是通過as_view()這個(gè)方法來分發(fā)不同的請(qǐng)求來實(shí)現(xiàn)了。我們可以利用這點(diǎn)來給類視圖的所有方法都應(yīng)用裝飾器。
一個(gè)比較簡(jiǎn)單但是不實(shí)用的辦法就是在項(xiàng)目的urls.py上面來實(shí)現(xiàn)。在分發(fā)請(qǐng)求的前面加上裝飾器。
url(r'^register$',ban_ip(views.register.as_view()))
雖然這樣比較方便,但是太不美觀了。裝飾器的優(yōu)雅都被它破壞了,那我們應(yīng)該怎么辦呢?
解決辦法:把a(bǔ)s_view()的方法重寫一下,給它加入裝飾器的功能。
class register(View): # 重寫請(qǐng)求分發(fā)方法,as_view()的核心語句 @method_decorator(ban_ip) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) def get(self,request): return render(request,"注冊(cè)頁面.html") def post(self,request): name = request.POST.get("name") password = request.POST.get("password") print(name) print(password) return HttpResponse("注冊(cè)成功")
(3)對(duì)類視圖的某個(gè)方法應(yīng)用裝飾器
@method_decorator(ban_ip,name='get') class register(View): def get(self,request): return render(request,"post.html") def post(self,request): title = request.POST.get("title") content = request.POST.get("content") print(title) print(content) return HttpResponse("發(fā)布成功")
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python練習(xí)之曾經(jīng)很火的小人畫愛心表白代碼
小編有個(gè)好兄弟最近在追妹子,跟妹子打得火熱!就差臨門一腳了,這一jio我?guī)兔ρa(bǔ)上去了!他問有沒有什么酷炫的表白方式,可以給人心動(dòng)的趕jio,表白的方式有許多種今天小編來教大家一個(gè)之前很火的小人畫愛心表白代碼2021-09-09Python實(shí)現(xiàn)的redis分布式鎖功能示例
這篇文章主要介紹了Python實(shí)現(xiàn)的redis分布式鎖功能,結(jié)合實(shí)例形式分析了Python操作redis分布式鎖與解鎖功能相關(guān)操作技巧,需要的朋友可以參考下2018-05-05Centos下實(shí)現(xiàn)安裝Python3.6和Python2共存
這篇文章主要介紹了Centos下實(shí)現(xiàn)安裝Python3.6和Python2共存,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08詳解如何使用Python和正則表達(dá)式處理XML表單數(shù)據(jù)
在日常的Web開發(fā)中,處理表單數(shù)據(jù)是一個(gè)常見的任務(wù),而XML是一種常用的數(shù)據(jù)格式,用于在不同的系統(tǒng)之間傳遞和存儲(chǔ)數(shù)據(jù),本文通過闡述一個(gè)技術(shù)問題并給出解答的方式,介紹如何使用Python和正則表達(dá)式處理XML表單數(shù)據(jù),需要的朋友可以參考下2023-09-09Python利用capstone實(shí)現(xiàn)反匯編
Capstone是一個(gè)輕量級(jí)的多平臺(tái)、多架構(gòu)的反匯編框架,該模塊支持目前所有通用操作系統(tǒng),反匯編架構(gòu)幾乎全部支持。本文就將利用他實(shí)現(xiàn)反匯編,感興趣的可以了解下2022-04-04python 遍歷列表提取下標(biāo)和值的實(shí)例
今天小編就為大家分享一篇python 遍歷列表提取下標(biāo)和值的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-12-12django中賬號(hào)密碼驗(yàn)證登陸功能的實(shí)現(xiàn)方法
這篇文章主要介紹了django中賬號(hào)密碼驗(yàn)證登陸功能的實(shí)現(xiàn)方法,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07