Django translations does not work
Asked Answered
B

11

16

I'm trying to get Django's translation system to work, following the tutorial here.

Here are my two views (one for direct output, one for template), neither one works.

def home(request):        
    output = _("hello") # (lazy)
    return HttpResponse(output)

def with_template(request):
    return render(request, 'translation_template.html')

here is the template file for the second view :

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

{% block content %}
<p>{% trans 'hello' %}</p>
{% language 'tr' %}
<p>{% trans 'hello' %}</p>
{% endlanguage %}
{% language 'tr-TR' %}
<p>{% trans 'hello' %}</p>
{% endlanguage %}
{% endblock %}

in my settings file, I added the following: (may add parts from before if requested)

LANGUAGE_CODE = 'en-us'    
# also tried LANGUAGE_CODE = 'tr'  and LANGUAGE_CODE = 'tr-TR'
PROJECT_DIR = os.path.dirname(__file__)

"""
# tried but didn't work
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS = (
    "django.contrib.context_processors.auth",
    "django.core.context_processors.i18n",
)
"""
LOCALE_PATHS = ( os.path.join(PROJECT_DIR, 'locale'), )
LANGUAGES = (
    ('tr', _('Turkish')),
    ('en', _('English')),
)

after saving these, I executed in the terminal :

python ./manage.py makemessages -l tr

then edited the newly created myproject/locale/tr/LC_MESSAGES/django.po to have this :

msgid "hello"
msgstr "merhaba"

then executed

python ./manage.py compilemessages

and restarted the server. the terminal commands show no error, but when I load the views, none of the "hello"s are translated.

What am I doing wrong here?

Thanks for any help!

Edit:

I found a suspicious code in en/../django.po, probably not relevant, but maybe it is. This is the very beginning of the file. The fuzzy (empty->empty) translation, could it be the problem?

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
Birr answered 16/4, 2015 at 23:47 Comment(7)
Negative score in less than 1 min. Why?Birr
Are you sure your browser is requesting the Turkish page? Try printing the current language in your template for debugging: {% get_language_info for LANGUAGE_CODE as current_lang %} and {{ current_lang.code }}Kibler
@halilpazarlama, have you included django.middleware.locale.LocaleMiddleware in MIDDLEWARE_CLASSES?Scorch
@Scorch yes. @ Selcuk it says en. I also added a translation for English, "eng_hello" but it doesn't apply.Birr
@halilpazarlama, try change your browser encoding/locale etc. to Turkish and see if it picks up the locale accordinglyScorch
Do you have lines starting with "fuzzy" in your .po file? If yes, remove them.Kibler
No they are not fuzzy. Shouldn't my trial of {% language 'tr' %} be doing this for me? Edit : I changed Chrome's settings to Turkish, @Selcuk's code shows tr this time, but again, no translation..Birr
B
31

I solved my issue. In my case, the problem was with the LOCALE_PATHS definition in settings.py.

I tested it in the view by :

from TranslationTest import settings
return HttpResponse(settings.LOCALE_PATHS)

It was showing home/myProjects/TranslationTest/TranslationTest/locale, however makemessages was producing the files in home/myProjects/TranslationTest/locale

so I changed my settings as follows :

SITE_ROOT = os.path.dirname(os.path.realpath(__name__))
LOCALE_PATHS = ( os.path.join(SITE_ROOT, 'locale'), )

and now it works.

But I still wonder, why didn't makemessages understand that it should create the files in the LOCALE_PATHS specificed by settings.py?

In my understanding, it always produces the locale files in SITE_ROOT/locale, so we should always set LOCALE_PATHS to this? If this is a default, why set it at all? I would appreciate further information on this issue.

Thanks for all the help !

Birr answered 17/4, 2015 at 13:35 Comment(1)
Print out settings.LOCALE_PATHS did help me solve this problem. the LOCALE_PATHS should include all 'locale' folder in the project. Thank you.Counteract
P
9

This happens if you have the locale middleware activated. By so doing, I think your session local depends on your browser locale.

if you comment the locale middleware, it should be working as expected.

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    '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',
]
Pharmacist answered 17/1, 2020 at 4:6 Comment(0)
T
7

and keep in mind if your language has a country in it e.g. fa-IR, in your settings file you must add:

LANGUAGE_CODE = 'fa-IR'

but when you want to call makemessages command you should change - to _:

makemessages -l fa_IR
Tuchun answered 28/4, 2020 at 7:11 Comment(1)
Related to this, from the docs: In all cases the name of the directory containing the translation is expected to be named using locale name notation. E.g. de, pt_BR, es_AR, etc.Bargello
T
7

I tried almost all of the offered solutions above without any success. Then I realised that I forgot to run compilemessages after makemessages command. So make sure you run:

python manage.py compilemessages 

After running makemessages. What the compilemessages command does is it converts .po files to .mo files in your locale directories. This is needed because .mo files are the only files that gettext can understand. Without .mo files translation won't work, which was the case for me.

Tocsin answered 21/1, 2022 at 21:36 Comment(0)
A
2

As of today, with Django 3.2 this issue is still present. In my case, I have the following setup:

C:.
├───documents
├───project
│   ├───apps
│   │   ├───accounts
│   │   │   ├───...
│   │   ├───common
│   │   │   ├───...
│   │   └───...
│   ├───locale
│   │   └───it
│   │       └───LC_MESSAGES
│   └───...
└───tests

The settings file is set in this way:

LANGUAGE_CODE = 'it'

LOCALE_PATHS = [
    os.path.join(Path(__file__).resolve().parent, "locale"),
]

LANGUAGES = [
   ('en', _('English')),
   ('it', _('Italian')),
]

The trick is in the definition of LOCALE_PATHS. Django-admin is in some way not synced with the Django environment.

Aubert answered 4/10, 2021 at 12:37 Comment(1)
thanks! I was having issues with my transaltions not appearing. This locale_path worked perfect!Farnham
A
1

I just want to remind something that cause me a tiny problem and it was that I should change language of browser(from options). However I did everything completely but I couldn't see the translated texts. And by the way I didn't want to use any specific url for seeing the translation.

Athalee answered 28/8, 2018 at 13:25 Comment(0)
M
0

For me commenting en line works OK

USE_I18N = True
USE_L10N = True
LANGUAGE_CODE = 'uk'
LANGUAGES = (
('uk', _('Ukrainian')),
# ('en', _('English')),
)

no locale folder in a project root, no custom LOCALE_PATHS

Melvinmelvina answered 22/5, 2020 at 10:23 Comment(0)
D
0

adding the local middle ware to the django middle ware worked for me 'django.middleware.locale.LocaleMiddleware',

Dumyat answered 23/4, 2021 at 6:31 Comment(0)
S
0

You might need to read this How Django discovers language preference.

TLDR;

The locale middleware decides the user language in the following order:

  1. i18n_patterns function in your root URLconf
  2. Failing that, it looks for a cookie set by the LANGUAGE_COOKIE_NAME setting
  3. Failing that, it looks at the Accept-Language HTTP header sent by your Browser
  4. Failing that, it uses the global LANGUAGE_CODE setting

In my case I followed a tutorial and I didn't had a clue what why my language was not changing.

I was already done with the locale folder where i had all the strings for both of languages translated and i had already setup the LOCALE_PATH and other stuffs correctly.

So for testing i changed the LANGUAGE_CODE to display the text in hindi but i was not aware of the language precedence stuff.

i had set the following in my settings

LANGUAGES = (
    ('hi', _('Hindi')),
    ('en', _('English')),
)
LANGUAGE_CODE = 'hi'

So what was happening was that i had no cookie that specified the language so the precedence fell for the browsers default language passed in http header.

So it never came to the LANGUAGE_CODE in my settings and the language in the request.LANGUAGE_CODE was set to en.

So for solving this issue i set the cookie to take precedence before my browser

from django.conf import settings
from django.http import HttpResponse
from django.utils import translation
user_language = 'hi'
translation.activate(user_language)
response = HttpResponse(...)
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, user_language)

I took this from here Explicitly setting the active language

Stacy answered 8/8, 2021 at 17:36 Comment(0)
T
0

you can try Candy Translate instead of Django native translations module. It is much easier, do not require to set up the middleware and basically does most of the work for you. It also allows you to manage the translations in the excel file which comes handy when you are sending the texts to the translators.

It comes with some limitations but for all my websites it was just enough and achieved much faster.

Tarkany answered 20/8, 2022 at 15:6 Comment(0)
H
0

You need to put the JavaScript code in a file inside the static folder(you need to run the collectstatic command) in order to the djangojs.po to be generated. Because Django by default look at this destination when dealing with JS files.

Henze answered 15/11, 2023 at 21:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.