【问题标题】:Using flask MethodView使用烧瓶方法视图
【发布时间】:2012-05-18 16:30:23
【问题描述】:

我正在尝试调整:

http://flask.pocoo.org/docs/views/

进入蓝图本身,(基于我看过的其他蓝图)。将 api 注册从应用程序抽象到蓝图初始化中。这是来自烧瓶文档的代码,有一些更改。

这似乎有效:

 class MyAPI(MethodView):

    def __init__(self, name):
        self.name = name
        bp = Blueprint(name, __name__)
        bp_endpoint = '{0}_api'.format(name)
        bp_url = '/{0}/'.format(name)
        bp_pk = '{0}_tag'.format(name)
        self.register_api(bp, bp_endpoint, bp_url, bp_pk, 'string')
        self._blueprint = bp

    def register_api(self, blueprint, endpoint, url, pk='id', pk_type='int'):
        view_func = self.as_view(endpoint)
        blueprint.add_url_rule(url, defaults={pk: None},
                         view_func=view_func, methods=['GET',])
        blueprint.add_url_rule(url, view_func=view_func, methods=['POST',])
        blueprint.add_url_rule('{0}<{1}:{2}>'.format(url, pk_type, pk), view_func=view_func,
                         methods=['GET', 'PUT', 'DELETE'])

    def get(self, my_tag):
         #... with post, put methods etc.

然后在我的应用程序中我可以这样做:

m = MyAPI('my')
app.register_blueprint(m._blueprint)

这似乎有效,注册网址以便我可以得到:

Map([<Rule '/my/' (POST, OPTIONS) -> my.my_api>,
 <Rule '/my/<my_tag>' (PUT, HEAD, DELETE, OPTIONS, GET) -> my.my_api>,
 <Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
 <Rule '/my/' (HEAD, OPTIONS, GET) -> my.my_api>])

但是,我现在去路线时遇到错误(我刚刚尝试过 GET):

Traceback (most recent call last):
  File "/media/686e26f8-c6d4-4448-8fe4-c19802726dcb/projects/1_current/private/pycleaver/venv/lib/python2.7/site-packages/flask/app.py", line 1518, in __call__
    return self.wsgi_app(environ, start_response)
  File "/media/686e26f8-c6d4-4448-8fe4-c19802726dcb/projects/1_current/private/pycleaver/venv/lib/python2.7/site-packages/flask/app.py", line 1506, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/media/686e26f8-c6d4-4448-8fe4-c19802726dcb/projects/1_current/private/pycleaver/venv/lib/python2.7/site-packages/flask/app.py", line 1504, in wsgi_app
    response = self.full_dispatch_request()
  File "/media/686e26f8-c6d4-4448-8fe4-c19802726dcb/projects/1_current/private/pycleaver/venv/lib/python2.7/site-packages/flask/app.py", line 1264, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/media/686e26f8-c6d4-4448-8fe4-c19802726dcb/projects/1_current/private/pycleaver/venv/lib/python2.7/site-packages/flask/app.py", line 1262, in full_dispatch_request
    rv = self.dispatch_request()
  File "/media/686e26f8-c6d4-4448-8fe4-c19802726dcb/projects/1_current/private/pycleaver/venv/lib/python2.7/site-packages/flask/app.py", line 1248, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/media/686e26f8-c6d4-4448-8fe4-c19802726dcb/projects/1_current/private/pycleaver/venv/lib/python2.7/site-packages/flask/views.py", line 83, in view
    self = view.view_class(*class_args, **class_kwargs)
**TypeError: __init__() takes exactly 2 arguments (1 given)**

aa而且这比我能想到的要低一两级。任何输入都对我错过的内容表示赞赏。我认为最初可能与 register_api 中的 view_func 有关。

编辑:

一个答案

class MyAPI(MethodView):  

    def __init__(self, name):
        self.name = name
        bp = Blueprint(name, __name__)
        self.endpoint = '{0}_api'.format(name)
        self.url = '/{0}/'.format(name)
        self.pk = '{0}_tag'.format(name)
        self._blueprint = bp
        self.register_api(self._blueprint, self.endpoint, self.url, self.pk)

    def register_api(self, bp, endpoint, url, pk ='id', pk_type='int'):
        view_func = self.__class__.as_view(endpoint)
        bp.add_url_rule(url, defaults={pk: None},
                     view_func=view_func, methods=['GET',])
        bp.add_url_rule(url, view_func=view_func, methods=['POST',])
        bp.add_url_rule('{0}<{1}:{2}>'.format(url, pk_type, pk), view_func=view_func,
                     methods=['GET', 'PUT', 'DELETE'])

【问题讨论】:

    标签: python flask


    【解决方案1】:

    我认为您可以将初始化方法只保留一个参数:

    def __init__(self):
        bp = Blueprint("what?", __name__)  # here
        bp_endpoint = '{0}_api'.format(name)
        bp_url = '/{0}/'.format(name)
        bp_pk = '{0}_tag'.format(name)
        self.register_api(bp, bp_endpoint, bp_url, bp_pk, 'string')
        self._blueprint = bp
    

    或在as_view 中提供足够的值而不修改您的初始化方法。

    def register_api(self, blueprint, endpoint, url, pk='id', pk_type='int'):
        view_func = self.as_view(endpoint, name="what?")  # here
        # ... omit ...
    

    但在我看来,在方法视图中创建蓝图并不是一个好主意。蓝图是一个子应用程序,应该由多个视图共享。

    【讨论】:

    • 我从这里拉过来:bitbucket.org/lost_theory/flask-stripe-blueprint/src 但情况不同。如果这种方式与 MethodView 不兼容,那么可以。我基本上是在尝试在没有大量代码的情况下在我的应用程序中实例化 api。嗯,我确实明白你的意思,但我的尝试缺乏技巧。
    • 因为它代表你对蓝图的看法,但这样做的目标是最终抽象出类以实例化传递给它的任何 db 对象的 api,本质上是对作为初始化的一部分,为每个实例量身定制的蓝图。
    • 然后我想register_api应该是静态方法或者类方法,因为as_view是MethodView实例的工厂方法。
    猜你喜欢
    • 2012-06-16
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    相关资源
    最近更新 更多