簡體   English   中英

在基於Django類的視圖中檢查視圖方法參數名稱

[英]Check view method parameter name in Django class based views

我在我的Django項目中創建了一個裝飾器,用於將參數值注入到裝飾方法的參數中。

我這樣做是通過使用inspect.getargspec來檢查方法中存在哪些參數並將它們放在kwargs 否則,由於方法中的參數數量不正確,我會收到錯誤。

雖然這在單個視圖方法中正常工作,但在Django基於類的視圖方面卻失敗了。

我相信這可能是因為裝飾器在類級別使用@method_decorator應用於dispatch方法而不是單獨的getpost方法。

我是一個蟒蛇新手,可能會忽略一些明顯的東西。

有沒有更好的方法來做我正在做的事情? 是否可以在基於類的視圖中獲取方法參數名稱?

我正在使用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):
    ...


由於遺留原因,我在此留下我以前的錯誤答案,不要在家里(或任何地方,在django,嘗試!!)嘗試這個!

如果我們觀察“裝飾類”文檔,我們可以看到以下內容:

或者,更簡潔地說,您可以改為裝飾類,並將要裝飾的方法的名稱作為關鍵字參數名稱傳遞:

因此,您必須更改@method_decoratorname參數以匹配將應用於的方法:

 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.GETrequest.POST

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM