python utils How to setup up Django translation in the correct way?



django-multilingual (4)

I've got an issue with translations not working on Django 1.6!. I've added to my settings.py

LANGUAGE_CODE = 'en-us'
ugettext = lambda s: s
LANGUAGES = (
    ('en', ugettext('English')),
    ('de', ugettext('German')),
)

Also added middlewares:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

as well as to my *.py files whenever I'm using a string which shall be l10nd:

from django.utils.translation import ugettext_lazy as _

My templates starting with

{% extends "base.html" %}
{% load i18n %}

and inside the template than I used the trans placeholder. E.g.

<h1>{% trans "Register a tank" %}</h1>

In fact the string is appearing inside locale/de/LC_MESSAGES/django.po when running as well I have translated them. E.g.

msgid "Register a tank"
msgstr "Einen neuen Tank anmelden"

My browser is set to request German content first: Browser settings

What did I miss?

P.S. The project I'm currently fuzzying around is hosted on github: https://github.com/frlan/blankspot


Check the cookies and the session -- according to How Django Discovers Language Preference, the process is this:

  1. language prefix in the URL, when using i18n_patterns in URLconf
  2. _language key in the current user's session
  3. django_language cookie (or as specified by settings.LANGUAGE_COOKIE_NAME)
  4. Accept-Language HTTP header (this is what your browser setting sends)
  5. settings.LANGUAGE_CODE

Since your browser settings are set to prefer 'de', I suspect the LocaleMiddleware must decide otherwise in one of the previous steps 1. - 3.


In my case, I used en-gb as the parameter to run

django-admin.py makemessages -l en-gb

Instead, it should be en_GB.

django-admin.py makemessages -l en_GB


Add the LOCALE_PATHS to settings.py and set it as bellow:

Note that LOCALE_PATHS must be a tuple(look at the comma at the end of the path)

import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale'),
)

Now based on LOCALE_PATHS, The locale folder should be in root of your project.

And be sure that you run django-admin.py makemessages -l de and django-admin.py compilemessages cmds from the root of your project.

djPrj
  |
  +---> djPrj
  |
  +---> djApp
  |
  +---> locale
  |
  +---> templates

Also rearrange your MIDDLEWARE_CLASSES to be LocaleMiddleware after SessionMiddleware and before CommonMiddleware that mentioned here:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

Restart your service(python manage.py runserver) and check again.


Just to ensure that your localization is applied to your django admin page with default django.mo file of django, do following test:

First in main urls.py of project replace patterns with i18n_patterns:

from django.conf.urls.i18n import i18n_patterns

urlpatterns = i18n_patterns('',
    url(r'^admin/', include(admin.site.urls)),
    # ...
)

Now go to Admin page with de prefix, like: http://127.0.0.1:8000/de/admin/ And Admin page should be show in German language.

Ok, are you able to see Admin page of django in de language ?

Also check your view with de prefix too.


According to your code of project, some sentences are not in trans block. put them as:

{% trans "your sentence" %}

Also you must use ugettext_lazy instead of ugettext in your code for views and models, (read here)

replace this:

from django.utils.translation import ugettext as _ 

with:

from django.utils.translation import ugettext_lazy as _

And now everything will work.


You need to enable the LocaleMiddleware in your settings, to tell Django to do language detection based on the browser-settings. Changing your language preferences effectly sets the Accept-Language header. You might need to check in an incognito window, because other means of language detection have a higher priority, such as the user's session and the django_language cookie.





django-i18n