2012-05-18 154 views
2

我試圖適應這一點:使用燒瓶MethodView

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)** 

aaand這是比我能想到的atm低一個或兩個水平。任何輸入讚賞我所錯過的。我認爲它最初可能與register_api中的view_func有關。

編輯:

排序的答案

類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']) 

回答

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

但在我看來,在方法視圖內創建藍圖並不是一個好主意。藍圖是一個子應用程序,應由許多觀點共享。

+0

我從這裏拉:https://bitbucket.org/lost_theory/flask-stripe-blueprint/src但不同的情況。如果這種方式與MethodView不兼容,那麼確定。我基本上試圖在我的應用程序中實例化apis,而不需要大量的代碼。嗯,我確實看到你的觀點,而我的嘗試缺乏技巧。 – blueblank

+0

因爲它表達了你對藍圖的正確態度,但是最終的目標是最終抽象出類來實例化傳遞給它的任何數據庫對象的API,本質上是一個爲每個實例定製和應用的藍圖的抽象作爲初始化的一部分。 – blueblank

+1

然後我認爲'register_api'應該是一個靜態方法或類方法,因爲'as_view'是MethodView實例的工廠方法。 –