Django Rest Framework的@api_view装饰器的用法和神秘的错误

时间:2019-02-02 16:18:41

标签: python django django-rest-framework django-rest-framework-jwt

我遇到了这个奇怪的错误,我的代码昨天(通过自动测试)运行良好,但今天却坏了。基本上,感觉就像@api_view装饰器损坏了,无法申请方法。 这是情况:

我有一个名为“ advance_orders”的方法,其包装如下:

is_show

注意: hack = True是我首次发现错误后出于调试目的添加的一小部分。

这里的方法@api_view(http_method_names=['POST'], hack=True) @permission_classes((IsAuthenticated,)) @check_wallet_token @disallow_disabled_users def advance_orders(request): # code that is irrelevant for this issue @check_wallet_token也无关紧要,我99.99%确信它们不是错误的来源(因为它们在昨天和以前在其他方法上被罚款,包装类似)

该函数的url映射为: @disallow_disabled_users

现在,在某些测试中,我有:

re_path(r'^vendor/orders/advance/$', vendor.advance_orders, name='advance_order'),

测试失败,在打印响应文本时,我发现: client = RequestsClient() # absolute_url == http://testserver/wallet/vendor/orders/advance/ # there are some helper methods which generate it... # the headers are irrelevant honestly r = client.post(absolute_url, headers=self.headers, data={"order_id": "asdf"}) print(r.text) self.assertEqual(r.status_code, 400) self.assertEqual(json.loads(r.text), {"display_message": "Missing order_id (int)."})

这是没有意义的!除非我做的是公然的错误,否则我肯定不会。

++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++

现在是我收集更多证据的时候。我进入了安装在虚拟环境中的DRF的源代码,并修改了两种方法以打印出额外的调试信息。

在views.py中,我如下更改{"detail":"Method \"POST\" not allowed."}

views.APIView.dispatch()

我修改的另一种方法是def dispatch(self, request, *args, **kwargs): """ `.dispatch()` is pretty much the same as Django's regular dispatch, but with extra hooks for startup, finalize, and exception handling. """ self.args = args self.kwargs = kwargs request = self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate? hack = False if request.META['PATH_INFO'] == '/wallet/vendor/orders/advance/': print("[HACK - views.py] Method identified as advance_order") hack = True try: self.initial(request, *args, **kwargs) # Get the appropriate handler method if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: print("[HACK - views.py] list of http_method_names associated with the function: {}".format(self.http_method_names)) handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc: response = self.handle_exception(exc) # and so on as usual...

decorators.api_view()

现在,我使用def api_view(http_method_names=None, exclude_from_schema=False, hack=False): """ Decorator that converts a function-based view into an APIView subclass. Takes a list of allowed methods for the view as an argument. """ http_method_names = ['GET'] if (http_method_names is None) else http_method_names if hack: print("[HACK - decorators.py] Provided http_method_names: {}".format(http_method_names)) # and so on as usual... 运行测试 在打印结果时,我们得到:

./manage.py test Wallet.tests.test_api_vendors.API_VendorTestCase --failfast

这绝对让我感到困惑,因为这意味着装饰器认识到我想允许'POST'方法,但是当执行我的视图'advance_order'时,'POST'不包括在允许的方法列表中。 / p>

所以我的问题是:我的错误是吗?如果是这样,怎么办?否则,我该怎么做才能解决这个问题? (删除__pycache__文件无效)。

P.S。对这个非常冗长的问题表示歉意,我只是想对我的问题很清楚。

0 个答案:

没有答案