From a6324ead24112604e5a3b8881b33bb0cb7b640e3 Mon Sep 17 00:00:00 2001 From: Martin Castro Laminrs Date: Sun, 31 May 2026 14:29:19 +0200 Subject: [PATCH] docs(readme): LocaleMiddleware section for translated payload fields (#630) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documents the requirement for ``django.middleware.locale.LocaleMiddleware`` in the consumer's MIDDLEWARE stack to make the API's ``gettext_lazy``-wrapped ``verbose_name`` / ``help_text`` / ``@admin.action(description=…)`` proxies resolve to the active request locale. The API package itself has no ``activate()`` call — by design, it piggybacks on Django's standard ``LocaleMiddleware.process_request`` (which calls ``translation.activate(language)`` after ``get_language_from_request``). With the middleware enabled, the JSON payload returns ``verbose_name`` etc. in the user's language; without it, the proxies stay un-resolved and read as English regardless of ``Accept-Language``. Django's ``startproject`` template does NOT include ``LocaleMiddleware`` by default, so a stock consumer who adds this package gets the English-only behaviour and a confusing gap between Django's own chrome (which IS translated when ``LocaleMiddleware`` is present in other paths) and the SPA's payloads. Calling this out in the README + showing the exact ``MIDDLEWARE`` line is the smallest doc change that closes the "why aren't my translated verbose_names showing up?" question. Half of #630 — the wire-side gap — is now documented. The SPA's own chrome strings (``"Add"`` / ``"Search"`` / ``"Loading…"``) are still hard-coded English; the message-catalog work is staged for a separate session. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/README.md b/README.md index a9dcceb..3e1d893 100644 --- a/README.md +++ b/README.md @@ -750,6 +750,52 @@ The SPA's HTTP client already sends `credentials: "include"`, so no frontend change is needed — only the Django-side cookie + CORS config above. Tracked: [#635](https://github.com/MartinCastroAlvarez/django-admin-react/issues/635). +### Translated `verbose_name` / `help_text` / action descriptions (`LocaleMiddleware`) + +The API package surfaces whatever your `ModelAdmin` declares — +including `gettext_lazy`-wrapped strings on `verbose_name`, +`help_text`, `@admin.action(description=…)`, etc. For those proxies +to resolve to the active request's language, you need Django's +**`LocaleMiddleware`** in your stack. It's not enabled by default +in `django-admin startproject`, and the package has no +ModelAdmin-level workaround: + +```python +# settings.py +USE_I18N = True +LANGUAGE_CODE = "en-us" # or your default +LANGUAGES = [ # the locales your translations cover + ("en", "English"), + ("es", "Español"), + # … +] + +MIDDLEWARE = [ + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.locale.LocaleMiddleware", # ← REQUIRED for i18n + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", +] +``` + +With `LocaleMiddleware` in place, the API payload's +`verbose_name` / `help_text` / `description` strings come back +translated per the request's `Accept-Language` header (or the +user's stored preference if you wire one), the same as Django's +HTML admin. The wire shape is identical regardless of locale — +only the human-readable strings change. + +**The SPA's own chrome strings** ("Add", "Search", "Save and +continue editing", "Loading…") are still hard-coded English. A +message-catalog refresh + `config.language` wire field is tracked +in [#630](https://github.com/MartinCastroAlvarez/django-admin-react/issues/630). Until that lands, non-English-primary shops +get translated `verbose_name` / `help_text` (via `LocaleMiddleware`) +but English chrome around them. + --- ## The API surface