HOWTO · Flask

Créer une URL dynamique à l'aide de url_for dans Flask

Découvrez comment Flask génère des URL avec `url_for()`, transmet des valeurs de route dynamiques, effectue des redirections et crée des liens dans les templates Jinja.

Sur cette page

Dans Flask, url_for() génère l’URL d’un endpoint, généralement le nom d’une fonction de vue. Transmettez les valeurs de route comme arguments nommés pour compléter un chemin dynamique. La fonction renvoie une chaîne contenant l’URL ; pour y envoyer le navigateur, renvoyez une réponse redirect() depuis une vue.

Comment url_for() construit une URL

Flask associe chaque vue à un endpoint. Par défaut, celui-ci porte le nom de la fonction de vue : url_for("index") désigne donc une vue nommée index. Flask recherche la route associée à cet endpoint et construit l’URL correspondante. Les liens restent ainsi liés aux définitions des routes, sans qu’il soit nécessaire de recopier leurs chemins à plusieurs endroits de l’application.

Le résultat est un chemin tel que / ou /users/Harry. Si une route comporte des segments variables, indiquez leurs valeurs au moyen d’arguments nommés correspondants. Les valeurs supplémentaires qui ne font pas partie de la route sont ajoutées comme paramètres de requête. Générer une URL ne déclenche ni requête ni redirection du visiteur.

Générer une URL à partir d’une fonction de vue

Cette petite application définit une vue d’accueil, une vue de profil, une vue qui effectue une redirection et une page Jinja. Son client de test demande la page Jinja et vérifie la réponse de redirection sans démarrer de serveur. Installez Flask dans l’environnement Python avant d’exécuter l’exemple. Dans l’environnement d’exécution fourni, le client de test a généré le lien et reçu une réponse 302 dont l’en-tête Location indique /users/Harry.

Exécutez cet exemple :

from flask import Flask, redirect, render_template_string, url_for

app = Flask(__name__)


@app.get("/")
def index():
    return "Home"


@app.get("/users/<string:user_name>")
def profile(user_name):
    return f"Profile: {user_name}"


@app.get("/go")
def go():
    return redirect(url_for("profile", user_name="Harry"))


@app.get("/links")
def links():
    return render_template_string(
        '<a href="{{ url_for(\'profile\', user_name=\'Josh\') }}">Profile</a>'
    )


with app.test_client() as client:
    page = client.get("/links")
    print(page.get_data(as_text=True))
    response = client.get("/go", follow_redirects=False)
    print(response.status_code)
    print(response.headers["Location"])
<a href="/users/Josh">Profile</a>
302
/users/Harry

L’argument endpoint est profile, le nom de la fonction de vue. Lorsque Flask traite /go, url_for() construit le chemin du profil et redirect() renvoie une réponse de redirection vers ce chemin. Le client de test affiche le lien généré, puis le statut de redirection et son en-tête Location. url_for("index") construirait le chemin de la page d’accueil de la même application.

Transmettre des valeurs de route dynamiques

La route /users/<string:user_name> déclare une variable nommée user_name ; l’appel url_for("profile", user_name="Harry") lui transmet une valeur. Flask insère cette valeur dans le chemin et l’encode dans l’URL si nécessaire. Veillez à faire correspondre l’endpoint et chaque nom de variable de route à la vue et aux arguments nommés ; sinon, Flask ne pourra pas trouver de route correspondante.

Pour une route comme /articles/<int:article_id>, transmettez un entier avec url_for("article", article_id=42). Les valeurs qu’aucune variable de route ne consomme, comme sort="recent", deviennent des paramètres de requête. Utilisez les variables de route pour structurer le chemin et les arguments nommés supplémentaires pour les données de requête.

Rediriger vers une URL générée

Dans une vue, renvoyez redirect(url_for("profile", user_name="Harry")). url_for() fournit le chemin de destination, tandis que redirect() crée la réponse HTTP qui indique au navigateur de s’y rendre. La vue /go de l’exemple suit ce modèle. Renvoyer uniquement url_for(...) placerait la chaîne de l’URL dans le corps de la réponse ; le navigateur ne serait pas redirigé.

Cette distinction est utile lorsque les routes changent : la redirection cible toujours la route enregistrée pour l’endpoint, ce qui évite d’inscrire un chemin en dur dans la vue. Choisissez le comportement de redirection en connaissance de cause : une redirection est une réponse à la requête en cours, et le navigateur demande la destination séparément.

Générer des liens dans des templates Jinja

Dans un template Jinja, utilisez le même endpoint et les valeurs de route dans l’attribut href d’un lien :

<a href="{{ url_for('profile', user_name='Josh') }}">Profile</a>

Ici, profile correspond au nom de la vue et user_name renseigne le segment de route obligatoire. L’exemple exécutable effectue le rendu de cette chaîne de template à /links ; le lien généré mène donc à la route du profil. Son libellé visible, « Profile », reste en anglais dans cet exemple. Pour un template enregistré dans un fichier, renvoyez-le avec Flask et render_template("index.html") ; placez ce fichier dans le répertoire templates de l’application. Ne transmettez pas de valeur de route que l’endpoint de destination ne déclare pas, et reprenez exactement le nom d’endpoint utilisé par l’application.