2012-05-10 21 views
8

Dentro de un plan frasco, que tengo:Usando Flask Blueprints, ¿cómo arreglar url_for para que no se rompa si se especifica un subdominio?

frontend = Blueprint('frontend', __name__) 

y la ruta a mi función de índice es:

@frontend.route('/') 
def index(): 
    #code 

Esto funciona bien, pero, estoy tratando de añadir un subdominio de la ruta, de este modo:

@frontend.route('/', subdomain='<var>') 
def index(var): 

Pero esto rompe la aplicación y el navegador escupe (entre otras cosas):

werkzeug.routing.BuildError 
BuildError: ('frontend.index', {}, None) 

frontend.index se llama en mi código en unos pocos lugares en un url_for ('frontend.index')

¿Cómo puedo obtener el url_for a trabajar cuando estoy incluyendo un subdominio? La única cosa en los documentos que se puede encontrar y creo que podría ser relevante es esto bajo http://flask.pocoo.org/docs/api/:

para integrar aplicaciones, el frasco tiene un gancho para interceptar URL construir errores a través Flask.build_error_handler. los resultados de la función url_for en un BuildError cuando la aplicación actual no tiene una dirección URL para el dado punto final y valores. Cuando lo hace, current_app llama a su build_error_handler si no es None, que puede devolver una cadena a uso como resultado de url_for (en lugar de url_for para aumentar la excepción BuildError) o vuelve a generar la excepción. Un ejemplo:

def external_url_handler(error, endpoint, **values): 
    "Looks up an external URL when `url_for` cannot build a URL." 
    # This is an example of hooking the build_error_handler. 
    # Here, lookup_url is some utility function you've built 
    # which looks up the endpoint in some external URL registry. 
    url = lookup_url(endpoint, **values) 
    if url is None: 
     # External lookup did not have a URL. 
     # Re-raise the BuildError, in context of original traceback. 
     exc_type, exc_value, tb = sys.exc_info() 
     if exc_value is error: 
      raise exc_type, exc_value, tb 
     else: 
      raise error 
    # url_for will use this result, instead of raising BuildError. 
    return url 

app.build_error_handler = external_url_handler 

Sin embargo, yo soy nuevo en Python (y programación) y no puede entender de dónde me gustaría poner este código o cómo iba a conseguir que la función a llamar cuando se produce un builderror.

Cualquier idea sería muy apreciada :)

+0

¿Ha intentado añadir '' _external = true'' a su url_for() llamar? –

+0

@chrickso: Vea mi respuesta. Parece que solo necesita proporcionar diferentes nombres de método. – pyfunc

Respuesta

13

En primer lugar, utilizar subdominios es necesario tener un valor para el SERVER_NAME configuration:

app.config['SERVER_NAME'] = 'example.net' 

Usted tiene una vista como esta:

frontend = Blueprint('frontend', __name__) 
@frontend.route('/', subdomain='<var>') 
def index(var): 
    return ... 

Con el fin de reconstruir la URL para este punto de vista , Flask necesita un valor para var. url_for('frontend.index') fallará ya que no tiene suficientes valores. Con el SERVER_NAME anterior, url_for('frontend.index', var='foo') devolverá http://foo.example.net/.

-3

no creo que esto es un problema con el frasco.

Usted está proporcionando dos funciones con el mismo nombre de método:

@frontend.route('/') 
def index(): 
    #code 

y

@frontend.route('/', subdomain='<var>') 
def index(var): 

Están envueltos de manera diferente, pero cuando flask.build_url se llama, es tirar debido a nombre de función sobrecargada . Esto parece incorrecto a primera vista.

Intenta proporcionar un nombre de función diferente para la segunda como

@frontend.route('/', subdomain='<var>') 
def index_var(var): 

Esto puede resolver su problema. Aunque no lo he probado.

9

Agregue el nombre del modelo en url_for. Ejemplo:

url_for('pay_sermepa.sermepa_cancel', _external=True) 
  • pay_sermepa: Nombre del modelo
  • sermepa_cancel: ruta
Cuestiones relacionadas