一 簡介:來學習下裝飾器,因為裝飾器廣泛應用在django框架中
二 前置基礎
1 Python 變量作用域的規則是 LEGB
LEGB含義解釋:
L —— Local(function);函數內的名字空間
E —— Enclosing function locals;外部嵌套函數的名字空間(例如closure)
G —— Global(module);函數定義所在模塊(文件)的名字空間
B —— Builtin(Python);Python內置模塊的名字空間
2 閉包函數
內層函數調用外層函數的環境變量
需要注意一點 1必須是外層函數 2是調用環境變量,可以是函數對象和具體變量
代碼示例
x=100
def fun()
x=50 #EG
def func() #閉包函數
x=0 #就近L
print(x)
return func #返回閉包函數對象,必須返回
fun()
三 裝飾器
一 場景
1 封閉且開放,不要修改裝飾器內部的代碼,對外開放所有功能
2 當執行完成,才會執行接下來的view函數
3 裝飾器本身會返回定義好的函數對象,如果驗證通過的話
4 裝飾器是典型的閉包函數應用代碼
二 語法
@log_required('函數名')
示例代碼#session辨別用戶是否登錄
def examineSession(func):
def wrapper(request, *args, **kwargs):
user = request.session.get("user", None)
if not user: #邏輯判斷,簡化版if not request.user(如果不存在用戶)
return render(request, "admin/login.html")
else:
res = func(request, *args, **kwargs)
return res #需要返回值
return wrapper #返回內置函數本身
index=examineSession(func) index()(這是最原始的調用方法)
@examineSession 語法糖,簡寫
三 總結
1 編寫裝飾器的關鍵是在於提取公共代碼進行封裝,封裝成一個內部函數類似於示例代碼的inner()
2 常見的時間統計,登錄驗證等固定功能
3 是否添加返回值看具體的場景
四 使用django裝飾器
1 from django.contrib.auth.decorators import login_required
2 @login_required
系統自帶裝飾器重定向會有問題,需要進行修改相關參數,(組成?next=下一個目標url)
3 修改 setting login_url配置為='/login'
4 相關問題
1 使用系統自帶裝飾器需要使用系統自帶的登錄相關葉敏
2 使用系統自帶裝飾器需要修改相關url綁定
五 待解決問題
1 ajax與login_required結合的問題
六
類視圖中使用裝飾器
#定義裝飾器
from django.utils.decorators import method_decorator
@method_decorator(my_decorator, name='get')#定義裝飾器名稱和請求方法
class DemoView(View):
def get(self, request):
print('get方法')
return HttpResponse('ok')
如果需要為類視圖的多個方法添加裝飾器,但又不是所有的方法(為所有方法添加裝飾器參考上面例子),可以直接在需要添加裝飾器的方法上使用method_decorator,如下所示
class DemoView(View):
@method_decorator(my_decorator) # 為get方法添加了裝飾器
def get(self, request):
print('get方法')
return HttpResponse('ok')
@method_decorator(my_decorator) # 為post方法添加了裝飾器
def post(self, request):
print('post方法')
return HttpResponse('ok')
def put(self, request): # 沒有為put方法添加裝飾器
print('put方法')
return HttpResponse('ok')