53π
Add LOCALE_PATHS
to settings.py
and set it as below:
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
Note that LOCALE_PATHS
must be a tuple (look at the comma at the end of the path).
Now based on LOCALE_PATHS
, the locale
folder should be in the root of your project.
And be sure that you run the commands django-admin.py makemessages -l de
and django-admin.py compilemessages
from the root of your project.
djPrj
|
+---> djPrj
|
+---> djApp
|
+---> locale
|
+---> templates
Also rearrange your MIDDLEWARE_CLASSES
to be LocaleMiddleware
after SessionMiddleware
and before CommonMiddleware
as 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 the default django.mo
file of Django, do the 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 the admin page with a de
prefix, like: http://127.0.0.1:8000/de/admin/
And the admin page should be shown in German.
OK, are you able to see the admin page of Django in German?
Also check your view with the de
prefix too.
According to your project code, some sentences are not in trans
blocks. Put them as:
{% trans "your sentence" %}
Also you must use ugettext_lazy
instead of ugettext
in your code for views and models (Read here and here.)
Replace this:
from django.utils.translation import ugettext as _
with:
from django.utils.translation import ugettext_lazy as _
And now everything will work.
4π
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
- [Django]-How to use dynamic foreignkey in Django?
- [Django]-Django, Turbo Gears, Web2Py, which is better for what?
- [Django]-Creating a dynamic choice field
2π
Please set translated string
in django.po
and then use python manage.py compilemessages
for e.g
#: path/to/python/module.py:23
msgid "Welcome to my site."
msgstr "put appropriate translated string here"
Suggestion-: You can use django-rosetta
package to add translated string
from UI interface. It is easy to add T-string from django-admin. https://github.com/mbi/django-rosetta
- [Django]-Do django db_index migrations run concurrently?
- [Django]-Create a field whose value is a calculation of other fields' values
- [Django]-How do I run another script in Python without waiting for it to finish?
2π
Check the cookies and the session β according to How Django Discovers Language Preference, the process is this:
- language prefix in the URL, when using i18n_patterns in URLconf
- _language key in the current userβs session
- django_language cookie (or as specified by settings.LANGUAGE_COOKIE_NAME)
- Accept-Language HTTP header (this is what your browser setting sends)
- 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.
- [Django]-How to automatically login a user after registration in django
- [Django]-How can I fill up form with model object data?
- [Django]-Using Python's os.path, how do I go up one directory?
1π
For example below, you can translate English to French. *I use Django 4.2.3.
First, create locale
folder just under django-project
as shown below. *You can see my answer explaining how to set templates:
django-project
|-core
| |-settings.py
| β-urls.py
|-my_app1
| |-views.py
| |-urls.py
| |-models.py
| |_admin.py
| β-apps.py
|-my_app2
|-templates
| β-index.html
β-locale # Here
Then, set core/settings.py
as shown below. *LocaleMiddleware
must be between SessionMiddleware
and CommonMiddleware
. 'en-us'
is set to LANGUAGE_CODE
by default in core/settings.py
:
# "core/settings.py"
MIDDLEWARE = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware', # Here
'django.middleware.common.CommonMiddleware',
...
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
from django.utils.translation import gettext_lazy as _
LANGUAGES = ( # Here
('en', _('English')),
('fr', _('French'))
)
And, Hello
and World
are translated with gettext() and outputted on console and index.html
is rendered in test()
in my_app1/views.py
as shown below. *You can see my answer explaining where to use gettext()
and gettext_lazy():
# "my_app1/views.py"
from django.shortcuts import render
from django.utils.translation import gettext as _
def test(request):
print(_("Hello"), _("World")) # Here
return render(request, 'index.html')
And, test()
path is set to urlpatterns
in my_app1/urls.py
as shown below. *You can see my question and my answer explaining how to translate url in Django:
# "my_app1/urls.py"
from django.urls import path
from . import views
app_name = "my_app1"
urlpatterns = [
path('', views.test, name="test") # Here
]
And, admin
and my_app1
paths are set to urlpatterns
with i18n_patterns() in core/urls.py
as shown below. *You can see my question and my answer explaining prefix_default_language=False with i18n_patterns()
:
# "core/urls.py"
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.i18n import i18n_patterns
urlpatterns = i18n_patterns(
path('admin/', admin.site.urls), # Here
path('my_app1/', include('my_app1.urls')) # Here
)
And, 3 tags are set in templates/index.py
as shown below. *For the translation in Django Templates, {% load i18n %}
is needed and {% translate %}
or {% trans %}
can translate:
# "templates/index.py"
{% load i18n %}
{% translate "Hello" %} {% trans "World" %}
And, name
field and person
model are translated in my_app1/models.py
as shown below:
# "my_app1/models.py"
from django.db import models
from django.utils.translation import gettext_lazy as _
class Person(models.Model):
first_name = models.CharField(
max_length=20, verbose_name=_("first name") # Here
)
last_name = models.CharField(
max_length=20, verbose_name=_("last name") # Here
)
class Meta:
verbose_name = _('person') # Here
verbose_name_plural = _('persons') # Here
And, this is my_app1/admin.py
below:
# "my_app1/admin.py"
from django.contrib import admin
from .models import Person
@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
pass
And, my_app1
is translated in my_app1/apps.py
as shown below:
# "my_app1/apps.py"
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class MyApp1Config(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'my_app1'
verbose_name = _('my_app1') # Here
Now, run the command below. *You can see my answer explaining the command below:
django-admin makemessages -l fr
Then, django.po
is created in locale/fr/LC_MESSAGES/
as shown below:
django-project
|-core
| |-settings.py
| β-urls.py
|-my_app1
| |-views.py
| |-urls.py
| |-models.py
| |_admin.py
| β-apps.py
|-my_app2
|-templates
| β-index.html
β-locale
β-fr
β-LC_MESSAGES
β-django.po # Here
Then, add Bonjour
, Monde
, Anglais
and Français
to each msgstr ""
respectively in locale/fr/LC_MESSAGES/django.po
as shown below:
# "locale/fr/LC_MESSAGES/django.po"
...
#: .\core\settings.py:140
msgid "English"
msgstr "Anglais" # Here
#: .\core\settings.py:141
msgid "French"
msgstr "Français" # Here
#: .\my_app1\apps.py:7
msgid "my_app1"
msgstr "mon_app1" # Here
#: .\my_app1\models.py:6
msgid "first name"
msgstr "prΓ©nom"
#: .\my_app1\models.py:7
msgid "last name"
msgstr "nom de famille"
#: .\my_app1\models.py:13
msgid "person"
msgstr "personne"
#: .\my_app1\models.py:14
msgid "persons"
msgstr "personnes"
#: .\my_app1\views.py:5 .\templates\index.html:3
msgid "Hello"
msgstr "Bonjour" # Here
#: .\my_app1\views.py:5 .\templates\index.html:3
msgid "World"
msgstr "Monde" # Here
...
Then, run the command below to compile django.po
to django.mo
. *You can see my answer explaining the command below:
django-admin compilemessages
Then, django.po
is compiled to django.mo
in locale/fr/LC_MESSAGES/
as shown below:
django-project
|-core
| |-settings.py
| β-urls.py
|-my_app1
| |-views.py
| |-urls.py
| |-models.py
| |_admin.py
| β-apps.py
|-my_app2
|-templates
| β-index.html
β-locale
β-fr
β-LC_MESSAGES
|-django.po
β-django.mo # Here
Now, http://localhost:8000/en/my_app1/
can show Hello World
as shown below:
And, Hello World
below is outputted on console:
Hello World
And, http://localhost:8000/fr/my_app1/
can show Bonjour Monde
as shown below:
And, Bonjour Monde
below is outputted on console:
Bonjour Monde
And, http://localhost:8000/en/admin/my_app1/person/add/
can show the English version of Django Admin including the app, model and field labels as shown below:
And, http://localhost:8000/fr/admin/my_app1/person/add/
can show the French version of Django Admin including the app, model and field labels as shown below:
In addition, you set English
as the 1st language in your browser as shown below. *This is Google Chrome:
Now, if you access http://localhost:8000/my_app1/
, then you are redirected to http://localhost:8000/en/my_app1/
as shown below:
And, you set French
as the 1st language in your browser as shown below.
Now, if you access http://localhost:8000/my_app1/
, then you are redirected to http://localhost:8000/fr/my_app1/
as shown below:
In addition again, you can remove i18n_patterns()
from admin
and my_app1
paths in core/urls.py
as shown below:
# "core/urls.py"
from django.contrib import admin
from django.urls import path, include
# from django.conf.urls.i18n import i18n_patterns
urlpatterns = [
path('admin/', admin.site.urls),
path('my_app1/', include('my_app1.urls'))
]
# urlpatterns = i18n_patterns(
# path('admin/', admin.site.urls), # Here
# path('my_app1/', include('my_app1.urls')) # Here
# )
Then, you set English
as the 1st language in your browser as shown below:
Now, http://localhost:8000/my_app1/
can show Hello World
as shown below:
And, you set French
as the 1st language in your browser as shown below.
Now, http://localhost:8000/my_app1/
can show Bonjour Monde
as shown below:
Lastly, you can easily create i18n switcher following my answer and my answer explaining how to create i18n switcher for Django and Django Admin respectively.
- [Django]-Is there a datetime Β± infinity?
- [Django]-Readonly for existing items only in Django admin inline
- [Django]-Add request.GET variable using django.shortcuts.redirect
0π
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]-How to get getting base_url in django template
- [Django]-Python: Getting the error message of an exception
- [Django]-Should I avoid multi-table (concrete) inheritance in Django by any means?