Mostrar URLs Amigables (slugs) con Flask y python-slugify

Haremos una app Flask simple: listamos productos, generamos slugs con python-slugify y al hacer click mostramos la URL amigable del producto.

Requisitos

bash
pip install flask python-slugify

Estructura mínima

A continuación, mostraremos la estructura mínima necesaria para la app.

bash
app.py
templates/
  index.html
  product.html
1Archivo app.py

En este archivo, mostraremos la app Flask completa, con la lógica para generar slugs y mostrar URLs amigables.

python
from flask import Flask, render_template, url_for, abort
from slugify import slugify

# Configuración básica de Flask
app = Flask(__name__)

# Datos en memoria (simulando DB)
PRODUCTS = [
  {"id": 1, "name": "Camiseta Blanca de Algodón", "price": 29.99},
  {"id": 2, "name": "Laptop Gamer RTX 4090", "price": 2499.00},
  {"id": 3, "name": "Auriculares Inalámbricos Bluetooth", "price": 79.5},
]

# Generar slug al arrancar (podrías guardarlo en DB en vez de generarlo cada vez)
for p in PRODUCTS:
  p["slug"] = slugify(p["name"])

# Rutas de la app
@app.route("/")
def index():
  # Mostrar lista de productos con enlaces a /producto/<slug>
  return render_template("index.html", products=PRODUCTS)

# Ruta para mostrar un producto por slug
@app.route("/producto/<slug>")
def producto(slug):
  # Buscar producto por slug
  prod = next((p for p in PRODUCTS if p["slug"] == slug), None)
  if not prod:
      abort(404)
  # Mostrar producto y la URL amigable (la misma que estás usando)
  friendly = url_for("producto", slug=prod["slug"])
  return render_template("product.html", product=prod, friendly_url=friendly)

# Iniciar app
if __name__ == "__main__":
  app.run(debug=True)
  Explicación

  • Guardamos productos en PRODUCTS y les añadimos slug.
  • / lista productos con links a /producto/<slug>.
  • /producto/<slug> busca por slug y muestra la URL amigable con url_for.

2El directorio templates/index.html

En este archivo, mostraremos la lista de productos con enlaces a /producto/<slug>.

html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Productos</title>
<style>body{font-family:system-ui,Segoe UI,Roboto;margin:32px} a{display:block;margin:8px 0}</style>
</head>
<body>
<h1>Productos</h1>
  <ul>
      {% for p in products %}
      <li>
          <a href="{{ url_for('producto', slug=p.slug) }}">
          {{ p.name }} — ${{ "%.2f"|format(p.price) }}
          </a>
      </li>
      {% endfor %}
  </ul>
<p>Haz click en un producto para ver su URL amigable.</p>
</body>
</html>
  Explicación

  • Lista simple usando Jinja2.
  • Cada enlace usa url_for('producto', slug=...) para construir la URL amigable.

3El directorio templates/product.html

En este archivo, mostraremos la información de un producto y su URL amigable.

html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{ product.name }}</title>
<style>body{font-family:system-ui,Segoe UI,Roboto;margin:32px}</style>
</head>
<body>
<h1>{{ product.name }}</h1>
  <p>Precio: ${{ "%.2f"|format(product.price) }}</p>

  <h3>URL amigable</h3>
  <code>{{ friendly_url }}</code>

  <p>
      Enlace absoluto: <a href="{{ friendly_url }}">{{ request.url_root.rstrip('/') + friendly_url }}</a>
  </p>

<p><a href="{{ url_for('index') }}">← Volver</a></p>
</body>
</html>
  Explicación

  • Muestra nombre, precio y friendly_url (ruta construida por Flask).
  • request.url_root permite mostrar el enlace absoluto (verás http://localhost:5000/producto/...).

4Ejecutar

En este paso, mostraremos cómo ejecutar la app y ver los resultados.

bash
python app.py
# Abrir http://127.0.0.1:5000/
  Explicación

  • Al entrar en la lista y hacer click en un producto verás la URL amigable generada por slugify.

  Notas rápidas y tips

  • Si usas DB, guarda el slug al crear el registro para evitar recalcularlo y para referencias estables.
  • Para slugs únicos: añade -id o verifica colisiones (ej. camiseta-1, camiseta-2).
  • slugify("Producto Ñ & Á")producto-n-y-a (normaliza caracteres).

😲 Puedes descargar el ejemplo completo Github.