2012-06-16 15 views
8

ho i seguenti itinerari pallone e un aiutante personalizzato:Flask - decoratore personalizzato interrompe il routing

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

mi sarei aspettato una richiesta GET a/test per tornare qualcosa di simile {"result":"Test success"} ma non è questo il caso. Invece, qualsiasi richiesta sembra corrispondere all'ultima rotta, ad esempio home. Perché?

Mi chiedo se questo è causato da una mancanza di isolamento tra le diverse chiamate a json_response?

Grazie in anticipo.

+0

'code = ret [0]; resp = ret [1] 'sarebbe più ordinato come' code, resp = ret' e 'resp = ret [0]' come 'resp, = ret' (anche se penso che non sia ancora come lo si vorrebbe usare , la tua funzione dovrebbe 'return {},' piuttosto che 'return {}'). Oltre a ciò, mi sembra corretto. –

+4

Solo un'ipotesi - la firma della funzione è interrotta, si consiglia di provare [functools.wraps] (http://docs.python.org/library/functools.html#functools.wraps). – Vidul

+0

Voglio vedere la risposta a questo –

risposta

11

Come Видул Петров detto che la soluzione è quella di utilizzare functools.wraps:

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

La ragione è che di Flask mappe sistema di routing di URL a "endpoint", e poi gli endpoint di visualizzare le funzioni. L'endpoint si imposta automaticamente sull'attributo __name__ della funzione di visualizzazione. In questo caso la funzione decorata è stata passata a app.route quindi l'endpoint era create_json_response per entrambe le regole e l'ultima vista definita per quell'endpoint veniva utilizzata in entrambi i casi.

functools.wraps prende il __name__ (e altri attributi) dalla funzione originale e corregge questo. È sempre una buona idea usarlo in involucri decorati.

+2

+1 per la spiegazione –

+4

flask ha un documento su questo: http://flask.pocoo.org/docs/patterns/viewdecorators/ – zchenah

Problemi correlati