← Blog

Cómo traducir un proyecto Django: makemessages, archivos .po y traducción automática

Traduce los archivos .po de tu proyecto Django a inglés, portugués y francés con python manage.py translate: extrae, traduce, escribe y compila. Con la salida real.

· 2 min de lectura

Traducir un proyecto Django suele ser así: makemessages, abrir cada .po, copiar los msgid en un traductor o en ChatGPT, pegar los msgstr uno a uno, rezar para que no se rompa ningún %(name)s y correr compilemessages. Y repetirlo con cada texto nuevo.

En esta guía lo hacemos con un solo comando, python manage.py translate, usando el paquete translate-projects-django. Todo lo que ves abajo (terminal y archivos .po) es la salida real de una ejecución en un proyecto de prueba.

Qué necesitas

  • Python 3.8 o superior y Django 3.2 o superior.
  • GNU gettext (xgettext y msgfmt), igual que para cualquier traducción en Django: sudo apt-get install gettext o brew install gettext.
  • Una cuenta gratis de Translate Projects con un proyecto y su API token (Primeros pasos).
  • La API key de tu proveedor de IA (Claude, OpenAI, DeepSeek o Gemini). No hay planes ni tarjeta: pagas solo los tokens que uses a tu proveedor.

1. Instala el paquete

pip install translate-projects-django

2. Configura settings.py

import os

INSTALLED_APPS = [
    # ...
    "translate_projects_django",
]

MIDDLEWARE = [
    # ...
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.locale.LocaleMiddleware",
    "django.middleware.common.CommonMiddleware",
    # ...
]

USE_I18N = True
LANGUAGE_CODE = "es"  # idioma base
LANGUAGES = [
    ("es", "Español"),
    ("en", "English"),
    ("pt-br", "Português (Brasil)"),
    ("fr", "Français"),
]
LOCALE_PATHS = [BASE_DIR / "locale"]
TRANSLATE_PROJECTS_API_KEY = os.environ.get("TRANSLATE_PROJECTS_API_KEY")

Los códigos de Django (pt-br, zh-hans) se convierten solos a los de la API. LANGUAGE_CODE es tu idioma base y nunca se traduce.

3. Marca tus textos como siempre

No cambia nada de lo que ya haces en Django: gettext en Python y {% translate %} en las plantillas.

# views.py (ejemplo)
from django.utils.translation import gettext as _

def home(request):
    message = _("Cerrar sesión")
{# templates/home.html (ejemplo) #}
{% load i18n %}
<h1>{% translate "Bienvenido a tu panel" %}</h1>
<p>{% blocktranslate %}Hola {{ name }}, tienes mensajes nuevos{% endblocktranslate %}</p>

4. Traduce

export TRANSLATE_PROJECTS_API_KEY=tu_token
python manage.py translate

Salida real (6 textos a inglés, portugués y francés):

[05:19:47 PM] 🎯 Start Generate Translations
              📂 6 texts found in es
[05:19:48 PM] ✅ Sources unchanged, upload skipped
📝 Translating (en)    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
📝 Translating (pt-br) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
📝 Translating (fr)    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
[05:19:50 PM] ⏱ extract 0.0s · upload 0.4s · compile 0.0s · total 2.5s · 7 HTTP requests
                 en: 6 filled, 0 missing, 0 rejected · translate 1.4s · download 0.4s ·
              write 0.0s
                 pt-br: 6 filled, 0 missing, 0 rejected · translate 1.6s · download 0.1s ·
                 fr: 6 filled, 0 missing, 0 rejected · translate 1.8s · download 0.3s ·
              🎉 Translations completed ✅

Dos segundos y medio en total. El comando ejecuta makemessages, traduce hasta 3 idiomas en paralelo, escribe los .po y termina con compilemessages. Así queda el francés:

# locale/fr/LC_MESSAGES/django.po
#: demo/templates/demo.html:2
msgid "Bienvenido a tu panel"
msgstr "Bienvenue sur votre tableau de bord"

#: demo/templates/demo.html:3
#, python-format
msgid "Hola %(name)s, tienes mensajes nuevos"
msgstr "Bonjour %(name)s, vous avez de nouveaux messages"

#: demo/templates/demo.html:4
msgid "<b>Guardar</b> cambios"
msgstr "<b>Enregistrer</b> les modifications"

#: demo/templates/demo.html:5
#, python-format
msgid "100 %% gratis"
msgstr "100 %% gratuit"

#: demo/views.py:3
msgid "Cerrar sesión"
msgstr "Se déconnecter"

#: demo/views.py:3
msgid "Configuración de la cuenta"
msgstr "Paramètres du compte"

Archivos que genera

locale/
├── en/LC_MESSAGES/django.po    ← y su django.mo
├── pt_BR/LC_MESSAGES/django.po
├── fr/LC_MESSAGES/django.po
└── .translate-projects.json    ← caché

Haz commit de los .po y de .translate-projects.json para que otras máquinas y tu CI salten los idiomas que ya están al día.

Comandos útiles

python manage.py translate --locale en   # solo un idioma
python manage.py translate --force       # descarga todo otra vez
  • Una segunda ejecución sin textos nuevos hace una sola petición y salta los idiomas completos: lo ya traducido no gasta tokens.
  • No edites los .po a mano: se reconstruyen en cada ejecución. Edita la traducción en el panel y corre con --force.
  • Limitación actual: los plurales (ngettext, blocktranslate count) todavía no se traducen y quedan en el idioma base.

Errores comunes

  • TRANSLATE_PROJECTS_API_KEY is not set in settings.py: exporta la variable y léela en settings.py.
  • El idioma de origen no es el predeterminado: LANGUAGE_CODE debe ser el idioma por defecto del proyecto.
  • MISSING_API_KEY: configura proveedor, modelo y key de IA en el proyecto.
  • CommandError: Can't find msguniq o xgettext: falta GNU gettext.

La guía completa está en doc.translateprojects.dev. Crea tu proyecto gratis y traduce tu proyecto Django hoy.