Skip to main content

translatebot-django

PyPI Downloads Tests Coverage License: MPL 2.0

Python Django

AI translation for Django, covering both your .po files and the content in your database. Run one command after each change and only the new text gets translated.

Documentation: https://translatebot.dev/docs/

The problem

Static strings are the easy part of translating a Django app. makemessages collects them into .po files, and plenty of tools can fill those in.

Database content is harder. Editors write product names, blog posts and category pages after you deploy, so that text never passes through gettext. With django-modeltranslation every language gets its own column, and someone has to work out which rows are missing which language. A translated slug still has to be a valid slug. Some of your existing translations may be machine output themselves, which makes them a poor source for the next language.

The usual options don't fit:

  • Copying text into Google Translate works for 20 strings. At 200 it falls apart, and you fix every broken placeholder by hand.
  • ChatGPT or Claude Code will translate a .po file well enough once. Next sprint you're prompting from scratch again, re-translating the whole file and hoping the terminology still matches.
  • Localization platforms charge per word. You also get portals and review workflows that a solo developer or small team doesn't need.

What TranslateBot does

TranslateBot adds a translate management command to your project. It translates whatever is missing and leaves existing translations alone.

Database content

With django-modeltranslation installed, python manage.py translate --models fills the empty language columns of every registered model. Pass model names to limit it to those models.

  • It translates from your default language whenever that column has text, since the other languages may already be machine translations. If it's empty, the first language with content is used.
  • Rows created before you installed modeltranslation only have text in the original column. TranslateBot reads it from there.
  • Slug fields are slugified again and cut to their max_length at a word boundary. File and image fields are skipped.
  • Columns that already have a translation stay as they are unless you pass --overwrite.

New content keeps arriving after you deploy, so the same function is available from Python. Call it from a Celery task or a signal handler when editors publish (see the Python API docs).

PO files

  • Only new and changed strings are translated. Add 10 strings in a sprint and you pay for 10, not the whole file.
  • A TRANSLATING.md file in your repo holds your glossary, tone and brand rules. Every run uses it, so a term you translated last month comes out the same today.
  • Placeholders such as %(name)s, {0} and %s and HTML tags are kept intact. LLM providers are told to preserve them, and DeepL gets them as protected tokens.
  • Every translation is checked before it's written, using the rules compilemessages applies to python-format and python-brace-format strings. A translation that drops or changes a placeholder is retried once. If it fails again, an untranslated entry gets it as a #, fuzzy draft. compilemessages skips fuzzy entries, so a bad translation never breaks your build, and the run ends with a list of drafts to review.
  • With LLM providers, each plural form of the target language gets its own translation (Polish, Russian, Arabic, …). pgettext contexts keep "May" the month apart from "May" the verb.

Everything else

  • It works with OpenAI, Anthropic, Google Gemini, Azure and any provider LiteLLM supports, or with DeepL.
  • One run covers every language in LANGUAGES. Adding a locale takes one line in your settings.
  • Strings are batched into as few API requests as possible.
  • python manage.py check_translations fails your CI build when strings are untranslated or fuzzy (CI docs).
  • You configure it in Django settings, and --llm-model overrides the model for a single run. The API key can also come from the TRANSLATEBOT_API_KEY environment variable.
  • The test suite covers 100% of the code.

Installation

To translate PO files only, install TranslateBot as a dev dependency:

uv add --dev translatebot-django

To translate model fields from your running app, install it as a regular dependency instead (see the Python API docs):

uv add translatebot-django

Optional extras: translatebot-django[deepl] for the DeepL provider, and translatebot-django[modeltranslation] for model field translation.

Supported versions

Each Django series is tested against the Python versions Django itself supports:

Django Python
4.2 3.10, 3.11, 3.12
5.0 3.10, 3.11, 3.12
5.1 3.10, 3.11, 3.12, 3.13
5.2 3.10, 3.11, 3.12, 3.13, 3.14
6.0 3.12, 3.13, 3.14
6.1 3.12, 3.13, 3.14

Quick start

# settings.py
import os

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

LANGUAGES = [("en", "English"), ("nl", "Dutch"), ("de", "German")]

TRANSLATEBOT_API_KEY = os.getenv("TRANSLATEBOT_API_KEY")
# The default; any LiteLLM model works, e.g. "claude-sonnet-5-5"
TRANSLATEBOT_MODEL = "gpt-6-luna"

On Python 3.10, set TRANSLATEBOT_MODEL to a model other than the default, such as gpt-4o-mini. The litellm versions that run there don't support gpt-6-luna properly.

The API key must belong to the provider of TRANSLATEBOT_MODEL. To use DeepL instead, set TRANSLATEBOT_PROVIDER = "deepl", put your DeepL key in TRANSLATEBOT_API_KEY and leave out TRANSLATEBOT_MODEL.

# Extract strings into .po files
python manage.py makemessages -l nl -l de

# Preview what would be translated (no API calls, but the key must be set)
python manage.py translate --dry-run

# Translate to all configured languages
python manage.py translate

# Compile for use
python manage.py compilemessages

Model fields

Model translation needs django-modeltranslation. Install the extra:

uv add "translatebot-django[modeltranslation]"

Add modeltranslation to INSTALLED_APPS, before django.contrib.admin if you use the admin:

INSTALLED_APPS = [
    "modeltranslation",
    # ...
    "translatebot_django",
]

Once your fields are registered for translation and migrated, fill their empty language columns:

python manage.py translate --models

When to use TranslateBot

For a one-off translation of 20 strings, ChatGPT works fine. TranslateBot is for ongoing projects where translations have to keep up with your code and your content.

It's a good fit when:

  • Your strings change every sprint and you're tired of re-translating whole files.
  • Editors add content to your database in one language and your users read it in others.
  • You support three or more languages and want them all updated in one run.
  • You want the same terminology every time, without pasting a glossary into a prompt.

Documentation

For full documentation, visit translatebot.dev/docs/

Contributing

Contributions are welcome. CONTRIBUTING.md covers the fork workflow, how to report a bug and the lint steps to run before you open a pull request. To get a local setup running:

git clone https://github.com/gettranslatebot/translatebot-django.git
cd translatebot-django
uv sync --extra dev
uv run pytest

License

This project is licensed under the Mozilla Public License 2.0. See the LICENSE file for details.

Credits

  • Built with LiteLLM for universal LLM provider support
  • Uses polib for .po file manipulation

Made with ❤️ for the Django community

Metadata

Release files for translatebot-django 1.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for translatebot-django 1.6.0
File Size Uploaded
translatebot_django-1.6.0.tar.gz 102.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for translatebot-django 1.6.0
File Interpreter ABI Platform
translatebot_django-1.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 154.6 kB

Release files / translatebot_django-1.6.0.tar.gz

Download URL translatebot_django-1.6.0.tar.gz
Size 102.9 kB
Tags Source
SHA-256 checksum
How to use checksums
86748b46cb4080313b8aa663b3cd453bf779cfa9c080d3cb47f88b30f544ea2b
BLAKE2b-256 checksum
How to use checksums
3b5df1e8cfadbeebf506487af3eddb7911f63590c653d43c08b12af87fd09f45
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / translatebot_django-1.6.0-py3-none-any.whl

Download URL translatebot_django-1.6.0-py3-none-any.whl
Size 51.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
eec591398c7dfd3ecaebf2611233c42534794abca68b893ae6f238deb47969c2
BLAKE2b-256 checksum
How to use checksums
51c6d1b36ad25751044a5f8a02eecb0c870ff2f1cfd6247981038dcf5048eb9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.6.0 This release

2 release files

1.5.0

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.4

2 release files

1.3.3

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.9.6

2 release files

0.9.5

2 release files

0.9.4

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.10

2 release files

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page