2013-01-01 47 views
3

我有一個燒瓶應用程序,作爲幾個MethodView s。在燒瓶中,如何在特定的可插入視圖上執行before_filter?

在我的一個MethodViews上,我想在每個請求前打開一個數據庫連接,並在請求後關閉它,非常類似於this

我知道如何使用全局函數@app.before_request@app.teardown_request函數,但這些函數會針對每個請求運行。我想要限制的版本只能在特定的MethodView中爲路由運行。

回答

2

你可以使用一個裝飾,將標記某些視圖依賴於數據庫。

NoSQLStore = {} 

class NoSQL(object): 
    """ fake """ 
    def query(self, key): 
     return '%s\n' % NoSQLStore.get(key, 'no such key') 
    def put(self, key, value): 
     NoSQLStore[key] = value 

def with_database(fn): 
    """ Decorator for functions, that need database access. 
     NoSQL object will be stored under ``g.db``. 
    """ 
    def connect_and_close(*args, **kwargs): 
     g.db = NoSQL() 
     __result = fn(*args, **kwargs) 
     # a real database should be somehow ``closed()`` here 
     return __result 
    return connect_and_close 

class StoreAPI(MethodView): 

    @with_database 
    def get(self): 
     return g.db.query(request.args.get('key')) 

    @with_database 
    def post(self): 
     key, value = str(random.randint(0, 1000)), str(random.randint(0, 1000)) 
     g.db.put(key, value) 
     return 'set %s => %s\n' % (key, value) 

可運行獨立的例子可以在這裏找到:https://gist.github.com/4424587

+1

+1我喜歡的裝飾方法。 MethodView可以自動將裝飾器應用於每個動作(http://flask.pocoo.org/docs/views/#decorating-views) –

2

如果要創建一個MethodView子類來做到這一點是簡單地增加一個被調用函數時,任何一種適當的方法是最簡單的方法:

class AutoConnectingView(MethodView): 
    def setup(self): 
     # Connect to the database here and store the connection on self. 
     self.db = connect_to_db() 

    def teardown(self): 
     self.db.close() 

    def dispatch_request(self, *args, **kwargs): 
     self.setup() 
     response = super(AutoConnectingView, self).dispatch_request(*args, **kwargs) 
     self.teardown() 
     return response 


class ARoomWithAView(AutoConnectingView): 
    def get(self): 
     rooms = self.db.execute("SELECT * FROM RoomsWithViews") 
     return render_template("rooms.html", rooms=rooms)