代码之家  ›  专栏  ›  技术社区  ›  Denis Steinman

两个装饰工产生冲突

  •  -1
  • Denis Steinman  · 技术社区  · 6 年前

    我需要同时使用两个装饰器,但它们相互冲突。这是我的路线:

    channel_args = {
        'name': fields.Str(required=True),
        'description': fields.Str(required=False, missing=None, default=None)
    }
    class ChannelListRoutes(Resource):
    
        @require_oauth
        @use_args(channel_args, locations=['json'])
        def post(self, args):
            channel = Channel()
            channel.name = args['name']
            channel.description = args['description']
            channel.user_id = current_token.user.id
            db.session.commit()
            db.session.flush()
            return ChannelJson(channel).to_json(), status.HTTP_201_CREATED
    

    哪里 require_oauth = ResourceProtector() 作者库 , @use_args 使用 网络参数 图书馆。
    我通过发送数据 卷曲 :

    curl -H "Authorization: Bearer {access_token}" -H "Content-Type: application/json" -X POST -d "{\"name\":\"Pets\"}" http://127.0.0.1:5000/api/channels
    

    请求后,我的应用程序刚刚崩溃:

    Traceback (most recent call last):
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
        return self.wsgi_app(environ, start_response)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
        response = self.handle_exception(e)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
        return original_handler(e)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
        reraise(exc_type, exc_value, tb)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/_compat.py", line 34, in reraise
        raise value.with_traceback(tb)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
        response = self.full_dispatch_request()
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
        return original_handler(e)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
        reraise(exc_type, exc_value, tb)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/_compat.py", line 34, in reraise
        raise value.with_traceback(tb)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
        rv = self.dispatch_request()
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
        return self.view_functions[rule.endpoint](**req.view_args)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/__init__.py", line 484, in wrapper
        return self.make_response(data, code, headers=headers)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/__init__.py", line 513, in make_response
        resp = self.representations[mediatype](data, *args, **kwargs)
      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/representations/json.py", line 21, in output_json
        dumped = dumps(data, **settings) + "\n"
      File "/usr/lib/python3.6/json/__init__.py", line 238, in dumps
        **kw).encode(obj)
      File "/usr/lib/python3.6/json/encoder.py", line 201, in encode
        chunks = list(chunks)
      File "/usr/lib/python3.6/json/encoder.py", line 437, in _iterencode
        o = _default(o)
      File "/usr/lib/python3.6/json/encoder.py", line 180, in default
        o.__class__.__name__)
    TypeError: Object of type 'function' is not JSON serializable
    

    附笔。 我试图更改decorators的顺序,但也没有帮助,尽管它生成了一个新的堆栈跟踪:

      File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/webargs/core.py", line 482, in wrapper
        return func(*new_args, **kwargs)
    TypeError: wrapper() takes 1 positional argument but 2 were given
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   bruno desthuilliers    6 年前

    reading the doc might help.. . require_oauth 需要一个“scope”参数,因此正确的语法是

    @require_oauth(scope)
    @use_args(channel_args, locations=['json'])
    def post(self, args):
        # ...
    

    也可以通过传递 None 明确地( @require_oauth(None) )或含蓄地通过调用 需要 没有任何争论,但是你 仍然 需要打电话给装修工:

    @require_oauth()
    @use_args(channel_args, locations=['json'])
    def post(self, args):
        # ...
    

    =>注意parens(python中的call运算符)。

    推荐文章