2012-06-16 38 views
8

我有以下瓶路線和一個自定義的助手:瓶 - 定製的裝飾打破了路由

from spots import app, db 
from flask import Response 
import simplejson as json 


def json_response(action_func): 
    def create_json_response(*args, **kwargs): 
     ret = action_func(*args, **kwargs) 
     code = 200 
     if len(ret) == 2: 
      code = ret[0] 
      resp = ret[1] 
     else: 
      resp = ret[0] 
     return Response(
      response=json.dumps(resp, indent=4), 
      status=code, 
      content_type='application/json' 
     ) 

    return create_json_response 


@app.route('/test') 
@json_response 
def test(): 
    return 400, dict(result="Test success") 


@app.route('/') 
@json_response 
def home(): 
    return 200, dict(result="Home success") 

我希望GET請求/測試返回類似{"result":"Test success"}但事實並非如此。相反,任何請求似乎都與最後一條路線相匹配,即home。爲什麼?

我不知道這是否是由於json_response的不同調用之間缺乏絕緣造成的?

在此先感謝。

+0

'code = ret [0]; resp = ret [1]'作爲'code,resp = ret'和'resp = ret [0]'作爲'resp,= ret'會更整齊一些(儘管我認爲這還不是你想要使用它的方式,你的函數需要'return {},'而不是'return {}')。除此之外,它對我來說看起來是正確的。 –

+4

只是一個猜測 - 函數的簽名被打破,你可能想嘗試[functools.wraps(http://docs.python.org/library/functools.html#functools.wraps)。 – Vidul

+0

我想查看這個 –

回答

11

正如ВидулПетров表示,解決方案是使用functools.wraps

import functools 
def json_response(action_func): 
    @functools.wraps(action_func) 
    def create_json_response(*args, **kwargs): 
     ... 
return create_json_response 

的原因是,瓶的路由系統將URL映射到「終點」,然後端點查看功能。端點默認爲視圖函數的__name__屬性。在這種情況下,裝飾函數被傳遞給app.route,因此兩個規則的端點爲create_json_response,並且在這兩種情況下都使用爲該端點定義的最後一個視圖。

functools.wraps採用原始函數的__name__(和其他屬性)並修復此問題。在裝飾包裝中使用它總是一個好主意。

+2

+1的解釋 –

+4

瓶有這個文件:http://flask.pocoo.org/docs/patterns/viewdecorators/ – zchenah