【问题标题】:Python Decorators Error- decorated_view() takes at least 2 arguments (1 given)"Python 装饰器错误 - decorated_view() 至少需要 2 个参数(给定 1 个)”
【发布时间】:2014-07-23 07:33:57
【问题描述】:

我想用我的装饰器装饰 Django 中的视图。基本上,我想在访问 API 的任何端点 URL 之前使用 auth-token 密钥对用户进行身份验证以授权其凭据:-

这是我的代码:-

class XYZResource(ModelResource):

    class Meta:
        queryset = XYZ.objects.all()
        resource_name = 'xyz'
        allowed_methods = ['get','post','delete','put']

    @roles_accepted('admin','staff')
    def obj_get(self, bundle, **kwargs):
        ..............

    @roles_accepted('admin','staff')
    def get_object_list(self, request): 
        ......


    @roles_accepted('admin','staff')
    def obj_create(self, bundle, **kwargs):
         ......

    @roles_accepted('admin','staff')
    def obj_update(self, bundle, **kwargs):
             ......


    @roles_accepted('admin','staff')
    def obj_delete(self, bundle, **kwargs):
             ......

这是我的装饰器:-

def roles_accepted(*roles):
    def wrapper(fn):
        def decorated_view(self,request,*args, **kwargs):
            if check_role(request) in roles  or check_role(request.request) in roles: # for POST,PUT,DELETE where bundle is passed, 
                return fn(self,request,*args, **kwargs)                               # auth_token is contained in bundle.request
            raise ImmediateHttpResponse(create_json_response({"error": "Unauthorized user"}, HttpUnauthorized)) 
        return decorated_view
    return wrapper

我遇到的错误是当我请求 POST/GET-ALL 时,它工作正常,但是当我执行 'GET/DELETE/PUT' 请求时,它说:-

{
  "error_message": "decorated_view() takes at least 2 arguments (1 given)",
  "traceback": "Traceback (most recent call last):\n\n  File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 195, in wrapper\n    response = callback(request, *args, **kwargs)\n\n  File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 435, in dispatch_detail\n    return self.dispatch('detail', request, **kwargs)\n\n  File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 458, in dispatch\n    response = method(request, **kwargs)\n\n  File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 1408, in put_detail\n    updated_bundle = self.obj_update(bundle=bundle, **self.remove_api_resource_names(kwargs))\n\nTypeError: decorated_view() takes at least 2 arguments (1 given)\n"
}

既然POSTPUT/DELETE/GET 包含相同的参数,那么在PUT/DELETE/GET 请求的情况下会发生什么不同?

【问题讨论】:

  • 我们可以看到您“执行'GET/DELETE/PUT'请求”的相关行吗?
  • 相关行??这是什么意思?

标签: python django python-decorators


【解决方案1】:

问题在于,您包装的某些函数接受名为request 的参数,而其他函数接受名为bundle 的参数,但您的装饰器始终调用该参数request。当 Tastypie 的内部尝试传递 bundle 关键字参数时,这会导致错误。您的装饰器不知道任何名为 bundle 的参数,因此它被收集在 **kwargs 中,并且您的装饰器不会收到 request 参数。

我对 Django 或 Tastypie 知之甚少,无法知道 request 和 bundle 之间应该有什么区别。如果它们在不同的名称下是相同的东西,您可以将该参数滚动到 kwargs 并让您的装饰器手动在其中查找名为 requestbundle 的参数。如果参数requestbundle 表示不同的东西,您可能需要编写两个不同的装饰器来适当地处理它们。

【讨论】:

  • 既然 POST 和 PUT/DELETE/GET 包含相同的参数,那么在 PUT/DELETE/GET 请求的情况下会发生什么不同呢? /requests 在 POST 的情况下成功,但在其他情况下则不成功,尽管它们都包含相同的参数/
  • @user1162512:我不知道您所说的“POST 和 PUT/DELETE/GET 包含相同的参数”是什么意思。我不知道这些请求调用了哪些方法。但是我可以在您的代码中看到其中一个方法具有request 参数,而其他方法具有bundle,并且我可以从回溯中看到Tastypie 正在尝试使用bundle 参数进行调用。请注意,仅仅因为您将相同的 HTTP 信息传递给 POST/GET 请求并不意味着将调用代码中的相同函数。 HTTP 参数和 Python 函数参数之间存在差异。
猜你喜欢
  • 2012-10-08
  • 2014-09-20
  • 2011-12-25
  • 1970-01-01
  • 2017-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多