Skip to main content

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 (xgettext and msgfmt), just like any translation in Django. On Windows use gettext para Windows.
  • A Translate Projects project and an API token. See Getting started.
Install gettext
# 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​

Terminal
pip install translate-projects-django

2. Configure settings.py​

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/*"]
SettingRequiredDescription
TRANSLATE_PROJECTS_API_KEYYesProject API token. Read it from an environment variable.
LANGUAGE_CODEYesBase language. It is never translated.
LANGUAGESYesTarget languages, using Django codes (pt-br, zh-hans); they are converted automatically to API codes (pt-BR, zh-Hans).
LOCALE_PATHSYesWhere the .po files are written (the first path).
TRANSLATE_PROJECTS_EXCLUDE_DIRSNoIt is passed to makemessages --ignore.

3. Mark your texts​

Use the standard Django tools:

views.py
from django.utils.translation import gettext as _

def home(request):
message = _("Bienvenido a mi sitio")
templates/home.html
{% load i18n %}
<html lang="{{ LANGUAGE_CODE }}">
<h1>{% translate "Hola mundo" %}</h1>
</html>

4. Translate​

Terminal
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.

Translation in the terminal

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 .po is rebuilt from the base language's .po every time that language is translated, so manual edits are lost. Edit the translations in the panel and run with --force.
  • Commit the .po files and .translate-projects.json so other machines and your CI skip the languages that are already up to date. You can upload the .mo files or generate them at deploy time with compilemessages.
  • Plural strings (ngettext, blocktranslate count) are not translated yet: they stay in the base language.

Result

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 in settings.py.
  • Invalid token (Token no válido): copy the project token again. Existing .po files are not modified.
  • The source language is not the default: LANGUAGE_CODE must 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 msguniq or xgettext: GNU gettext is missing; install it as indicated in Requirements.
Free

🚀 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.

Create free account →

Support

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.

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! ☕

Buy me a coffee