[英]Check view method parameter name in Django class based views
我在我的Django項目中創建了一個裝飾器,用於將參數值注入到裝飾方法的參數中。
我這樣做是通過使用inspect.getargspec
來檢查方法中存在哪些參數並將它們放在kwargs
。 否則,由於方法中的參數數量不正確,我會收到錯誤。
雖然這在單個視圖方法中正常工作,但在Django基於類的視圖方面卻失敗了。
我相信這可能是因為裝飾器在類級別使用@method_decorator
應用於dispatch
方法而不是單獨的get
和post
方法。
我是一個蟒蛇新手,可能會忽略一些明顯的東西。
有沒有更好的方法來做我正在做的事情? 是否可以在基於類的視圖中獲取方法參數名稱?
我正在使用Python 2.7和Django 1.11
裝飾者
def need_jwt_verification(decorated_function):
@wraps(decorated_function)
def decorator(*args, **kwargs):
request = args[0]
if not isinstance(request, HttpRequest):
raise RuntimeError(
"This decorator can only work with django view methods accepting a HTTPRequest as the first parameter")
if AUTHORIZATION_HEADER_NAME not in request.META:
return HttpResponse("Missing authentication header", status=401)
jwt_token = request.META[AUTHORIZATION_HEADER_NAME].replace(BEARER_METHOD_TEXT, "")
try:
decoded_payload = jwt_service.verify_token(jwt_token)
parameter_names = inspect.getargspec(decorated_function).args
if "phone_number" in parameter_names or "phone_number" in parameter_names:
kwargs["phone_number"] = decoded_payload["phone"]
if "user_id" in parameter_names:
kwargs["user_id"] = decoded_payload["user_id"]
if "email" in parameter_names:
kwargs["email"] = decoded_payload["email"]
return decorated_function(*args, **kwargs)
except JWTError as e:
return HttpResponse("Incorrect or expired authentication header", status=401)
return decorator
基於類的視圖
@method_decorator([csrf_exempt, need_jwt_verification], name="dispatch")
class EMController(View):
def get(self, request, phone_number, event_id):
data = get_data()
return JsonResponse(data, safe=False)
def post(self, request, phone_number, event_id):
return JsonResponse("Operation successful", safe=False)
編輯:
在方法級別應用裝飾器的明顯解決方案不適用於Django基於類的視圖。 您需要在url配置中應用裝飾器或將裝飾器應用於dispatch方法。
編輯:我發布了與我正在探索的解決方法相關的代碼,將參數名稱作為參數傳遞給裝飾器。
我發現這篇文章: 函數裝飾器在Django中基於類的視圖上有參數
這可能會為您的問題提供答案:
如果要傳遞帶參數的裝飾器,您只需:
評估decorator-creator函數中的參數。
將評估值傳遞給
@method_decorator
。
上面提到的和在考慮中的鏈接答案中提供的代碼,你應該:
injectables=[inject_1, inject_2, ..., inject_n]
decorators = [csrf_exempt, need_jwt_verification(injectables)]
@method_decorator(decorators, name="dispatch")
class EMController(View):
...
如果我們觀察“裝飾類”文檔,我們可以看到以下內容:
或者,更簡潔地說,您可以改為裝飾類,並將要裝飾的方法的名稱作為關鍵字參數名稱傳遞:
因此,您必須更改 @method_decorator
的name
參數以匹配將應用於的方法:
decorators = [csrf_exempt, need_jwt_verification(injectables=[])] @method_decorator(decorators, name='get') @method_decorator(decorators, name='post') class EMController(View):
就個人而言,我更喜歡將裝飾器置於他們將應用的特定方法之上:
class EMController(View): @method_decorator(decorators) def get(self, request, phone_number, event_id): ... @method_decorator(decorators) def post(self, request, phone_number, event_id): ...
在庫的當前狀態下,我想要的東西似乎是不可能的。 所以這就是我最終的目標。
parameter_names = inspect.getargspec(decorated_function).args
if "phone_number" in parameter_names or "phone_number" in injectables:
kwargs["phone_number"] = decoded_payload["phone"]
if "user_id" in parameter_names:
kwargs["user_id"] = decoded_payload["user_id"]
if "email" in parameter_names:
kwargs["email"] = decoded_payload["email"]
request.__setattr__("JWT", {})
request.JWT["phone_number"] = decoded_payload["phone"]
request.JWT["user_id"] = decoded_payload["user_id"]
request.JWT["email"] = decoded_payload["email"]
此裝飾器將根據需要自動填充基於方法的視圖中的參數。
但它也會為請求對象注入一個JWT
屬性,以供基於類的視圖使用。 像request.GET
和request.POST
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.