37 votes

Comment utiliser url_for si ma méthode comporte plusieurs annotations de route?

J'ai donc une méthode accessible par plusieurs routes:

 @app.route("/canonical/path/")
@app.route("/alternate/path/")
def foo():
    return "hi!"
 

Maintenant, comment puis-je appeler url_for("foo") et savoir que je vais obtenir le premier itinéraire?

65voto

Nemoden Points 4520

Ok. Il a fallu se plonger dans l' werkzeug.routing et flask.helpers.url_for code, mais j'ai compris. Il suffit de changer l' endpoint pour la route (en d'autres mots, vous le nom de votre itinéraire)

@app.route("/canonical/path/", endpoint="foo-canonical")
@app.route("/alternate/path/")
def foo():
    return "hi!"

@app.route("/wheee")
def bar():
    return "canonical path is %s, alternative is %s" % (url_for("foo-canonical"), url_for("foo"))

va produire

canonique chemin d'accès est /canonique/chemin/, alternative est /autre/chemin/

Il y a un inconvénient de cette approche. Flacon se lie toujours la dernière route définie pour le point de terminaison définis implicitement (foo dans votre code). Devinez ce qui arrive si vous redéfinir le point de terminaison? Tous vos url_for('old_endpoint') lèvera werkzeug.routing.BuildError. Alors, je pense que la bonne solution pour l'ensemble de la question est la définition canonique de chemin le dernier et le nom de l' alternative:

""" 
   since url_for('foo') will be used for canonical path
   we don't have other options rather then defining an endpoint for
   alternative path, so we can use it with url_for
"""
@app.route('/alternative/path', endpoint='foo-alternative')
""" 
   we dont wanna mess with the endpoint here - 
   we want url_for('foo') to be pointing to the canonical path
"""
@app.route('/canonical/path') 
def foo():
    pass

@app.route('/wheee')
def bar():
    return "canonical path is %s, alternative is %s" % (url_for("foo"), url_for("foo-alternative"))

51voto

Armin Ronacher Points 16894

Les règles en Flacon sont uniques. Si vous définissez l'absolu même URL pour la même fonction par défaut clash parce que vous êtes en train de faire quelque chose qui nous vous empêcher de faire car c'est de notre point de vue, c'est le mal.

Il y a une raison pourquoi vous voulez avoir plus d'une adresse URL absolue de la même extrémité et qui est rétro-compatibilité avec une règle qui existait dans le passé. Depuis WZ0.8 et Flacon de 0,8 vous pouvez spécifier explicitement un alias pour un itinéraire:

@app.route('/')
@app.route('/index.html', alias=True)
def index():
    return ...

Dans ce cas, si l'utilisateur demande /index.html Flacon rendra automatiquement une rediriger de façon permanente à juste /.

Cela ne signifie pas qu'une fonction ne peut être lié à plus d'une url, mais dans ce cas, vous avez besoin de changer le point de terminaison:

@app.route('/')
def index():
    ...

app.add_url_rule('/index.html', view_func=index, endpoint='alt_index')

Ou sinon:

@app.route('/')
@app.route('/index.html', endpoint='alt_index')
def index():
    ...

Dans ce cas, vous pouvez définir une vue une seconde fois sous un nom différent. Cependant, ce est quelque chose que vous voudrez généralement à éviter, car le point de vue de la fonction serait de demande de chèque.point de terminaison pour voir ce qui est appelé. Au lieu de mieux faire quelque chose comme ceci:

@app.route('/')
def index():
    return _index(alt=False)

@app.route('/index.html')
def alt_index():
    return _index(alt=True)

def _index(alt):
    ...

Dans ces deux cas, l'URL de génération est - url_for('index') ou url_for('alt_index').

Vous pouvez également le faire sur le système de routage de niveau:

@app.route('/', defaults={'alt': False})
@app.route('/index.html', defaults={'alt': True})
def index(alt):
    ...

Dans ce cas de l'url de génération est - url_for('index', alt=True) ou url_for('index', alt=False).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X