2012-06-16 18 views
8

tengo las siguientes rutas frasco y un ayudante de encargo:Frasco - decorador de costumbre rompe el enrutamiento

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

yo esperaría una solicitud GET a/de prueba para volver algo así como {"result":"Test success"} pero ese no es el caso. En cambio, cualquier solicitud parece coincidir con la última ruta, es decir, home. ¿Por qué?

Me pregunto si esto se debe a alguna falta de aislamiento entre las diferentes llamadas al json_response?

Gracias de antemano.

+0

'code = ret [0]; resp = ret [1] 'sería más nítido como' code, resp = ret', y 'resp = ret [0]' as 'resp, = ret' (aunque creo que todavía no es la forma en que te gustaría usarlo) , su función necesitaría 'return {},' en lugar de 'return {}'). Más allá de eso, me parece correcto. –

+4

Solo supongo que la firma de la función está rota, es posible que desee probar [functools.wraps] (http://docs.python.org/library/functools.html#functools.wraps). – Vidul

+0

Quiero ver la respuesta a esto –

Respuesta

11

Como Видул Петров dijo que la solución es utilizar functools.wraps:

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

La razón es que los mapas del sistema de enrutamiento de URL matraz para "puntos finales", y luego los puntos finales para ver funciones. El punto final se predetermina al atributo __name__ de la función de vista. En este caso, la función decorada pasó a app.route, por lo que el punto final fue create_json_response para ambas reglas y la última vista definida para ese punto final se utilizó en ambos casos.

functools.wraps toma el __name__ (y otros atributos) de la función original y lo corrige. Siempre es una buena idea usarlo en envoltorios decorados.

+2

+1 para la explicación –

+4

matraz tiene un documento sobre esto: http://flask.pocoo.org/docs/patterns/viewdecorators/ – zchenah