Django
The translate-projects-django package adds the python manage.py translate command: it extracts your strings, translates them into each language in settings.LANGUAGES, writes the .po files and compiles them.
Requirements
- Python 3.8 or higher and Django 3.2 or higher.
- GNU gettext (
xgettextandmsgfmt), just like any translation in Django. On Windows use gettext para Windows. - A Translate Projects project and an API token. See Getting started.
# Debian / Ubuntu
sudo apt-get install gettext
# macOS
brew install gettext
# Docker
RUN apt-get update && apt-get install -y gettext
1. Install the package
pip install translate-projects-django
2. Configure 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" # Base language: the default language of the project
LANGUAGES = [
("es", "Español"),
("en", "English"),
("pt-br", "Português (Brasil)"),
("fr", "Français"),
]
LOCALE_PATHS = [BASE_DIR / "locale"] # The first path is used
TRANSLATE_PROJECTS_API_KEY = os.environ.get("TRANSLATE_PROJECTS_API_KEY")
# Optional: folders that makemessages ignores
TRANSLATE_PROJECTS_EXCLUDE_DIRS = ["venv/*", "node_modules/*"]
| Setting | Required | Description |
|---|---|---|
TRANSLATE_PROJECTS_API_KEY | Yes | Project API token. Read it from an environment variable. |
LANGUAGE_CODE | Yes | Base language. It is never translated. |
LANGUAGES | Yes | Target languages, using Django codes (pt-br, zh-hans); they are converted automatically to API codes (pt-BR, zh-Hans). |
LOCALE_PATHS | Yes | Where the .po files are written (the first path). |
TRANSLATE_PROJECTS_EXCLUDE_DIRS | No | It is passed to makemessages --ignore. |
3. Mark your texts
Use the standard Django tools:
from django.utils.translation import gettext as _
def home(request):
message = _("Bienvenido a mi sitio")
{% load i18n %}
<html lang="{{ LANGUAGE_CODE }}">
<h1>{% translate "Hola mundo" %}</h1>
</html>
4. Translate
export TRANSLATE_PROJECTS_API_KEY=tu_token
python manage.py translate # All languages in LANGUAGES
python manage.py translate --locale en # Only one language
python manage.py translate --force # Download everything again
The language in --locale must be in LANGUAGES and differ from LANGUAGE_CODE. With --locale fr --force only that language is translated again.

Files it generates
locale/
├── en/LC_MESSAGES/django.po ← and its compiled django.mo
├── pt_BR/LC_MESSAGES/django.po
├── fr/LC_MESSAGES/django.po
└── .translate-projects.json ← cache
The command runs makemessages for the base language, translates up to 3 languages in parallel, writes the .po files (pt-br becomes pt_BR) and finishes with compilemessages. Translations that change a placeholder (%(name)s, %s, {name}) are discarded so that compilemessages never fails.
- Each translated
.pois rebuilt from the base language's.poevery time that language is translated, so manual edits are lost. Edit the translations in the panel and run with--force. - Commit the
.pofiles and.translate-projects.jsonso other machines and your CI skip the languages that are already up to date. You can upload the.mofiles or generate them at deploy time withcompilemessages. - Plural strings (
ngettext,blocktranslate count) are not translated yet: they stay in the base language.

Cache and --force
A second run without new strings makes a single request and skips the languages that are already complete (stored in locale/.translate-projects.json). Use --force to download everything again, for example after editing translations in the panel. More details in Cache and errors.
Common errors
TRANSLATE_PROJECTS_API_KEY is not set in settings.py: export the variable and read it insettings.py.- Invalid token (
Token no válido): copy the project token again. Existing.pofiles are not modified. The source language is not the default:LANGUAGE_CODEmust be the project's default language.- Missing AI key (
MISSING_API_KEY): configure the provider, the model and the key in the project; missing strings are retried on the next run. - Partial translation, 5xx or network errors: they are retried automatically and incomplete languages are requested again on the next run.
CommandError: Can't find msguniqorxgettext: GNU gettext is missing; install it as indicated in Requirements.
🚀 Automate your translations for free
Translate Projects is free. You create your project, connect your AI provider's key, and only pay them what you spend.
- No plans or credit card required: All features are available from day one.
- Use your own AI: Claude, OpenAI, DeepSeek, or Gemini. Your key is stored encrypted.
- Shared translation network: If a text has already been translated, you receive it instantly without spending your key.
- Admin panel: Review and edit all your translations from one place.
We're here to help
If you have any questions, need help, or want to contribute, don't hesitate to contact me. I'm available to support you with whatever you need.
- Website: neiderruiz.com
- GitHub: @neiderruiz
- Twitter: @neiderruiz
- YouTube: Neider Ruiz
Support the Project
If this project has been helpful to you, I invite you to buy me a coffee. Your support helps me keep improving and creating valuable content. Thanks for being here! ☕