HOWTO · Flask
Crear URL dinámica usando url_for en Flask
Aprende a generar URL con Flask `url_for()`, pasar valores dinámicos de ruta, redirigir a la URL generada y crear enlaces en plantillas Jinja.
En esta página
En Flask, url_for() genera la URL de un endpoint, que suele ser el nombre de una función de vista. Pasa los valores de ruta como argumentos con nombre para completar una ruta dinámica. La función devuelve una cadena con la URL; para dirigir el navegador a esa dirección, devuelve una respuesta redirect() desde una vista.
Cómo genera una URL url_for()
Flask registra cada vista con un endpoint. De forma predeterminada, el endpoint es el nombre de la función de vista, así que url_for("index") hace referencia a una vista llamada index. Flask busca la ruta de ese endpoint y genera la URL correspondiente. Así, los enlaces quedan vinculados a las definiciones de ruta, sin necesidad de repetir las cadenas de ruta por toda la aplicación.
El resultado es una ruta como / o /users/Harry. Si una ruta contiene segmentos variables, proporciona sus valores con argumentos con nombre que coincidan. Los valores adicionales que no forman parte de la ruta se añaden como parámetros de consulta. Generar una URL no envía una solicitud ni redirige a quien visita la página.
Generar una URL a partir de una función de vista
La siguiente aplicación sencilla define una vista de inicio, una vista de perfil, una vista que redirige y una página Jinja. Su cliente de pruebas solicita la página Jinja y comprueba la respuesta de redirección sin iniciar un servidor. Instala Flask en el entorno de Python antes de ejecutar el ejemplo. En la ejecución proporcionada, el cliente de pruebas generó el enlace y recibió una respuesta 302 con /users/Harry en la cabecera Location.
Ejecuta este ejemplo:
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
El argumento del endpoint es profile, el nombre de la función de vista. Cuando Flask recibe una solicitud a /go, url_for() genera la ruta del perfil y redirect() devuelve una respuesta de redirección a esa ruta. El cliente de pruebas muestra el enlace generado y, después, el estado de la redirección y su cabecera Location. url_for("index") generaría la ruta de inicio de la misma aplicación.
Pasar valores de ruta dinámicos
La ruta /users/<string:user_name> declara una variable llamada user_name; la llamada url_for("profile", user_name="Harry") proporciona un valor para esa misma variable. Flask inserta el valor en la ruta y, cuando hace falta, lo codifica para usarlo en una URL. Mantén alineados el endpoint, el nombre de cada variable de ruta, la vista y los argumentos con nombre; de lo contrario, Flask no podrá encontrar una ruta que coincida.
Para una ruta como /articles/<int:article_id>, pasa un entero con url_for("article", article_id=42). Los valores que no corresponden a una variable de ruta, como sort="recent", se convierten en parámetros de consulta. Usa las variables de ruta para definir la estructura de la ruta y los argumentos con nombre adicionales para los datos de consulta.
Redirigir con una URL generada
Dentro de una vista, devuelve redirect(url_for("profile", user_name="Harry")). url_for() proporciona la ruta de destino y redirect() crea la respuesta HTTP que indica al navegador que navegue hasta ella. La vista /go del ejemplo sigue este patrón. Si devolvieras solo url_for(...), la cadena con la URL se enviaría como cuerpo de la respuesta; el navegador no navegaría a esa dirección.
Esta diferencia resulta útil cuando cambian las rutas: la redirección sigue apuntando a la ruta registrada para el endpoint, así que la vista no necesita incluir una ruta fija. Elige deliberadamente el comportamiento de redirección, ya que esta es una respuesta a la solicitud actual y el navegador solicita el destino por separado.
Generar enlaces en plantillas Jinja
En una plantilla Jinja, usa el mismo endpoint y los valores de ruta en el href de un enlace:
<a href="{{ url_for('profile', user_name='Josh') }}">Profile</a>
Aquí, profile coincide con el nombre de la vista y user_name completa el segmento de ruta obligatorio. El ejemplo ejecutable renderiza esta cadena de plantilla en /links, por lo que el enlace generado apunta a la ruta del perfil. La etiqueta visible del enlace permanece como «Profile», en inglés. Si guardas la plantilla en un archivo, devuélvela con render_template("index.html") desde Flask y coloca el archivo en el directorio templates de la aplicación. No pases un valor de ruta que el endpoint de destino no declare y usa exactamente la grafía del endpoint definida en la aplicación.