# General Translation Knowledge Base: General Translation frente al framework de traducción de Django: ¿necesitas ambos?
URL: https://generaltranslation.com/es/kb/general-translation-vs-django-i18n.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Usa el framework de traducción de Django y General Translation de forma conjunta. Django se encarga de la extracción de mensajes, la selección del idioma y el renderizado. General Translation rellena sus archivos PO, incluidas las formas plurales, con la terminología de tu producto y la revisión en el panel de control. Tus plantillas y patrones de URL siguen igual, y las traducciones se actualizan a la par que tu código.
Category: Internacionalización
Last updated: 2026-10-16
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-16

Django incluye un framework completo de internacionalización (i18n): marcas las cadenas con `gettext` y `{% translate %}`, `makemessages` las extrae a un archivo PO por idioma, `compilemessages` genera los archivos `.mo` que carga Django y `LocaleMiddleware` elige el idioma de cada solicitud. General Translation añade el paso de traducción entre la extracción y la compilación: su CLI lee tu catálogo en inglés y escribe los archivos PO traducidos que carga Django.

## Lo que el framework de traducción de Django hace bien

* **Marcar cadenas en cualquier parte.** `gettext` y `ngettext` [cubren el código Python](https://docs.djangoproject.com/en/5.2/topics/i18n/translation/#internationalization-in-python-code), `gettext_lazy` se encarga de las cadenas definidas en tiempo de importación, como los campos de modelos y las etiquetas de formularios, `pgettext` añade contexto a las palabras ambiguas, y `{% translate %}` y `{% blocktranslate %}` (con `count` para plurales) cubren las plantillas.
* **Extracción y compilación integradas.** `makemessages` ejecuta `xgettext` de GNU gettext sobre tus archivos Python y plantillas, y [fusiona las cadenas nuevas en un archivo `django.po`](https://docs.djangoproject.com/en/5.2/topics/i18n/translation/#message-files) por idioma, en `locale/<locale>/LC_MESSAGES/`. Un comentario `# Translators:` encima de una cadena se incluye en el archivo PO para quien vaya a traducirla.
* **Selección de idioma por solicitud.** `LocaleMiddleware` [comprueba el prefijo de la URL](https://docs.djangoproject.com/en/5.2/topics/i18n/translation/#how-django-discovers-language-preference) añadido por `i18n_patterns`, luego una cookie de idioma, después la cabecera `Accept-Language` y, por último, `LANGUAGE_CODE`. Solo elige idiomas incluidos en `LANGUAGES` y, si no encuentra `de-at`, recurre a `de`.
* **Más que cadenas.** Las fechas y los números [se formatean según la configuración regional activa](https://docs.djangoproject.com/en/5.2/topics/i18n/formatting/), y `JavaScriptCatalog` sirve al navegador un catálogo `djangojs` aparte.
* **Django ya viene traducido.** El panel de administración y las aplicaciones integradas [incluyen catálogos para unos cien idiomas](https://github.com/django/django/tree/stable/5.2.x/django/contrib/admin/locale), y el framework es gratuito bajo la licencia BSD.

## Lo que Django deja en tus manos

[La propia documentación de Django](https://docs.djangoproject.com/en/5.2/topics/i18n/translation/#compiling-message-files) describe el paso del que no se encarga: cuando los traductores hayan completado el archivo de mensajes, tienes que compilarlo. Aquí tienes una plantilla con un plural:

```html title="shop/templates/shop/inbox.html"
{% load i18n %}
<p>{% blocktranslate count counter=count %}{{ counter }} file{% plural %}{{ counter }} files{% endblocktranslate %}</p>
```

Con Django 5.2, `python manage.py makemessages -l ru` copia en la cabecera la regla de pluralización de cuatro formas del ruso desde el propio catálogo de Django, pero solo genera dos huecos vacíos para la entrada:

```text title="locale/ru/LC_MESSAGES/django.po"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || "
"(n%100>=11 && n%100<=14)? 2 : 3);\n"

#: shop/templates/shop/inbox.html:2
#, python-format
msgid "%(counter)s file"
msgid_plural "%(counter)s files"
msgstr[0] ""
msgstr[1] ""
```

En una prueba, rellenar solo esas dos posiciones produjo un catálogo que `compilemessages` compiló sin errores, y la página renderizó &quot;1 файл&quot; y &quot;3 файла&quot;, pero luego &quot;5 files&quot; en inglés para una cantidad de cinco, porque la posición que la regla asigna al cinco nunca se llegó a escribir. Un catálogo vacío falla con el mismo silencio: sin nada en `pt_BR`, la página `/pt-br/` se renderizó íntegramente en inglés. Cada nueva cadena que marcas vuelve a iniciar el ciclo en todos los idiomas.

Además, Django no va más allá de las cadenas del código. El contenido almacenado en tu base de datos, como nombres de productos o páginas, requiere un paquete de terceros: django-modeltranslation [añade un campo por idioma](https://django-modeltranslation.readthedocs.io/en/latest/registration.html) a los modelos que registres, y django-parler guarda las traducciones en una tabla aparte. Ambos te ofrecen un lugar donde guardar las traducciones, pero ninguno las escribe por ti.

## Cómo traducir los archivos PO de Django con General Translation

La CLI de General Translation lee el catálogo en inglés que Django ya mantiene, traduce cada entrada y genera un archivo PO para cada idioma de destino justo donde Django espera encontrarlo. Mantén actualizado el catálogo en inglés con `makemessages`:

```bash
python manage.py makemessages -l en
```

Después, configura `gt.config.json` para que apunte a él. Esta configuración se comprobó con `gt` 2.26.5:

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["es", "pl", "pt_BR"],
  "customMapping": {
    "pt_BR": { "code": "pt-BR" }
  },
  "files": {
    "pot": {
      "include": ["locale/[locale]/LC_MESSAGES/*.po"],
      "transformationFormat": "PO"
    }
  }
}
```

Aquí hay algunos detalles importantes, todos explicados en la [referencia del formato PO / POT](/docs/cli/reference/formats/po-pot-files):

* **`pot` es la clave tanto para archivos PO como POT.** `transformationFormat` debe ser `PO`; si no se indica, la salida sigue siendo una plantilla sin traducir.
* **Los directorios de configuración regional usan los nombres de Django.** La CLI reemplaza `[locale]` por cada configuración regional tal cual la escribas. [`customMapping`](/docs/cli/reference/config#custom-mapping) asocia el directorio `pt_BR` de Django con el código de configuración regional estándar `pt-BR`.
* **`*.po` incluye todos los dominios**, también `djangojs.po` si ejecutas además `makemessages -d djangojs -l en`.

Con la CLI configurada (consulta el [Inicio rápido de la CLI](/docs/cli/quickstart)), ejecuta [`npx gt translate`](/docs/cli/reference/commands/translate) y después `python manage.py compilemessages`. General Translation envía cada entrada acompañada, como contexto, de toda la información que el archivo PO tiene sobre ella: el `msgctxt`, los comentarios `# Translators:`, las referencias de origen y opciones como `python-format`. En las entradas plurales, escribe la cabecera `Plural-Forms` del idioma de destino, rellena todos los huecos `msgstr[n]` que esa cabecera requiere y comprueba que los marcadores de posición como `%(counter)s` se mantengan intactos. En ruso, se aplica la regla estándar de gettext de tres formas; como Django lee la regla de cada catálogo por separado, no entra en conflicto con la regla de cuatro formas del catálogo ruso propio de Django.

Las entradas sin cambios reutilizan sus traducciones anteriores, de modo que la siguiente ejecución solo traduce lo que ha cambiado; `--force` vuelve a traducirlo todo. Si tus archivos PO ya contienen traducciones, ejecuta [`npx gt upload`](/docs/cli/reference/commands/upload) antes de generar otras nuevas. Para conservar los cambios locales que hagas después, sincronízalos con [`npx gt save-local`](/docs/cli/reference/commands/save-local) antes de la siguiente ejecución de traducción.

Aquí es donde se nota la ventaja de la plataforma completa. Un glosario y prompts personalizados en un [grupo de contexto](/docs/platform/dashboard/guides/defining-context-for-translations) mantienen la coherencia de los términos del producto y del tono en tus catálogos de Django y en los demás proyectos asignados al grupo. Los revisores pueden [editar cada entrada PO](/docs/platform/dashboard/guides/reviewing-translations), incluidas sus formas plurales, desde el panel de control. Ejecuta `makemessages`, [`gt translate`](/docs/cli/reference/commands/translate) y `compilemessages` en CI para actualizar las traducciones en cada lanzamiento.

Para el contenido de la base de datos y otros textos que solo existen en tiempo de ejecución, la API de General Translation traduce cadenas bajo demanda ([`POST /v2/translate`](/docs/platform/openapi/reference/translation/translate-content)); el almacenamiento de los resultados corre de tu cuenta, por ejemplo en los campos por idioma de django-modeltranslation.

Instala Node.js en la máquina donde se ejecuta la CLI. Django sigue sirviendo los catálogos compilados con su entorno de ejecución de Python actual.

## Comparativa rápida: el framework de traducción de Django frente a General Translation

| Característica                              | Framework de traducción de Django                                                                               | General Translation                                                         |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| Marca cadenas en el código y las plantillas | Sí: `gettext`, `{% translate %}` y más                                                                          | Usa las llamadas de mensajes de Django que ya tienes                        |
| Extrae cadenas a archivos PO                | Sí, con `makemessages`                                                                                          | Lee los archivos que genera `makemessages`                                  |
| Escribe traducciones                        | No                                                                                                              | Sí, con [`npx gt translate`](/docs/cli/reference/commands/translate)        |
| Formas plurales                             | Cabecera del catálogo de Django; tú rellenas cada forma                                                         | Escribe la cabecera del idioma de destino y rellena todas las formas        |
| Contexto para la traducción                 | Comentarios `# Translators:` y `msgctxt` en el archivo PO                                                       | Lo mismo, además del glosario y los prompts personalizados                  |
| Idioma por solicitud y prefijos de URL      | Sí, con `LocaleMiddleware` e `i18n_patterns`                                                                    | Conserva el enrutamiento y la selección de idioma de Django                 |
| Contenido de la base de datos               | Paquetes de terceros como django-modeltranslation                                                               | Traducción mediante API en tiempo de ejecución; tú almacenas los resultados |
| Costo                                       | Gratuito y de código abierto ([BSD](https://docs.djangoproject.com/en/5.2/faq/general/#how-is-django-licensed)) | [Traducción con pago por uso](https://generaltranslation.com/pricing)       |

## Cuándo usar cada opción

Usa solo el framework de Django cuando tengas traductores o un sistema de gestión de traducciones que ya rellene tus archivos PO, cuando publiques en uno o dos idiomas y puedas traducir a mano, o cuando cada traducción deba escribirla una persona. Añade General Translation cuando quieras que todos los archivos PO se rellenen en todos los idiomas con cada cambio, con las formas plurales completas y una terminología coherente, sin una ronda de traducción entre la fusión y el lanzamiento.

No tienes que elegir entre uno y otro: Django se encarga del marcado, la extracción, la compilación y la selección de idioma, y General Translation se ocupa de la traducción. No hay nada que migrar, porque tus plantillas, tu middleware y tus patrones de URL no cambian.

## Conclusiones clave

* El framework de traducción de Django renderiza las traducciones, pero no las escribe. Si falta una forma plural o el catálogo está vacío, se vuelve al inglés sin ningún error de compilación.
* General Translation traduce el catálogo en inglés generado por `makemessages` a un archivo PO por idioma. Tus plantillas, tu middleware y tus patrones de URL no cambian.
* Para cada entrada plural, General Translation escribe la cabecera `Plural-Forms` del idioma de destino y todas las posiciones `msgstr[n]`, y pasa `msgctxt` y los comentarios para traductores como contexto.

## Related questions

- [General Translation frente a GNU gettext: ¿necesitas ambos?](https://generaltranslation.com/es/kb/general-translation-vs-gettext.mdx): Conserva GNU gettext para la extracción y el renderizado, y añade General Translation para generar y mantener los archivos PO. General Translation incorpora las notas para traductores y el contexto de los mensajes en la generación, aplica una terminología compartida y ofrece a los revisores un editor en el panel de control. Tus llamadas actuales a gettext y tus catálogos compilados siguen como están.
- [General Translation frente a Babel y Flask-Babel: ¿cuál deberías usar?](https://generaltranslation.com/es/kb/general-translation-vs-flask-babel.mdx): Babel da formato a fechas, números y monedas para cualquier configuración regional y gestiona catálogos de gettext, y Flask-Babel lo integra con Flask, pero ninguno de los dos traduce tus cadenas. La CLI de General Translation rellena los archivos PO de Babel para cada idioma, formas plurales incluidas, para que puedas seguir usando Flask-Babel y dejar de traducir catálogos a mano.
- [General Translation vs. Rails I18n: ¿necesitas ambos?](https://generaltranslation.com/es/kb/general-translation-vs-rails-i18n.mdx): Rails I18n busca mensajes y da formato a fechas y números. General Translation genera las traducciones, las mantiene al día a medida que cambia tu texto en inglés y ofrece a tu equipo un panel de control para revisarlas. Usa ambos para publicar catálogos de Rails traducidos en cada lanzamiento.
- [¿Por qué usar General Translation en lugar de un TMS (Smartling, Lokalise, Phrase, Crowdin o Transifex)?](https://generaltranslation.com/es/kb/general-translation-vs-tms.mdx): Un sistema de gestión de traducciones (TMS) como Smartling, Lokalise, Phrase, Crowdin o Transifex coordina a los traductores, pero los ingenieros siguen teniendo que extraer las cadenas, enviarlas, esperar las traducciones y volver a integrarlas en el producto. General Translation traduce el contenido de tu código junto con su contexto, incluye todos los idiomas en cada lanzamiento y funciona con bibliotecas de código abierto, sin dependencia de proveedor.
- [General Translation vs. i18next, react-intl y next-intl: ¿qué biblioteca de i18n deberías usar?](https://generaltranslation.com/es/kb/general-translation-vs-i18n-libraries.mdx): Las bibliotecas de código abierto como i18next, react-intl y next-intl no traducen nada. Muestran las traducciones que tú proporcionas en un archivo de catálogo para cada idioma, escritas por ti, por tus traductores o por un servicio externo. Las bibliotecas de General Translation también son de código abierto y cumplen la misma función, pero además General Translation se encarga de traducir, usando tu código como contexto.

## Previous and next questions

- Previous question: [General Translation frente a GNU gettext: ¿necesitas ambos?](https://generaltranslation.com/es/kb/general-translation-vs-gettext.mdx)
- Next question: [General Translation vs. i18n-tasks: ¿cuál deberías usar?](https://generaltranslation.com/es/kb/general-translation-vs-i18n-tasks.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/es/kb/sitemap.md) for every article.
