You can change and save LANGUAGE_CODE in settings.py
with i18n switcher so the language is not changed even if you use different browsers.
First, you need to do the following 3 steps:
Add lang
field to User
model following one of two ways(my answer) to create custom User
model. *I recommend more customizable way(my answer) than less customizable way(my answer)
lang = models.CharField(max_length=20, blank=True)
Set translation(English and French) in Djnago following my answer.
Create i18n switcher for both or either Django and/or Django Admin following my answer and my answer respectively.
Next, create special/middleware/
, special/views/
and special/conf/urls/
folders with __init__.py
(Empty file) and copy locale.py
, i18n.py
and i18n.py
from django/middleware/locale.py
, django/views/i18n.py
and django/conf/urls/i18n.py
in your virtual environment to special/middleware/
, special/views/
and special/conf/urls/
folders respectively as shown below:
django-project
|-core
| |-settings.py
| |-urls.py
| └-special
| |-middleware
| | |-__init__.py
| | └-locale.py # Here
| |-views
| | |-__init__.py
| | └-i18n.py # Here
| └-conf
| |-__init__.py
| └-urls
| |-__init__.py
| └-i18n.py # Here
|-my_app1
| |-views.py
| |-urls.py
| |-models.py
| |_admin.py
| └-apps.py
|-my_app2
|-templates
| └-index.html
└-locale
└-fr
└-LC_MESSAGES
└-django.po
Then, replace 'django...LocaleMiddleware',
with 'core...LocaleMiddleware',
in core/settings.py
as shown below:
# "core/settings.py"
MIDDLEWARE = [
...
"django.contrib.sessions.middleware.SessionMiddleware",
# 'django.middleware.locale.LocaleMiddleware',
'core.special.middleware.locale.LocaleMiddleware',
"django.middleware.common.CommonMiddleware",
]
Then, replace path(... include("django..."))
with path(... include("core..."))
in core/urls.py
as shown below:
# "core/urls.py"
urlpatterns += [
# path("i18n/", include("django.conf.urls.i18n"))
path("i18n/", include("core.special.conf.urls.i18n"))
]
Then, add the code below to core/special/middleware/locale.py
as shown below:
# "core/special/middleware/locale.py"
...
from django.contrib import auth # Add
...
class LocaleMiddleware(MiddlewareMixin):
...
def process_request(self, request):
...
if (
not language_from_path
and i18n_patterns_used
and not prefixed_default_language
):
language = settings.LANGUAGE_CODE
# ↓ For more customizable `User` model ↓
user = auth.get_user(request)
if user.is_authenticated and user.lang:
language = user.lang
# ↑ For more customizable `User` model ↑
# ↓ For less customizable `User` model ↓
user = auth.get_user(request)
if user.is_authenticated and user.userprofile.lang:
language = user.userprofile.lang
# ↑ For less customizable `User` model ↑
translation.activate(language)
request.LANGUAGE_CODE = translation.get_language()
Then, add the code below to core/special/views/i18n.py
as shown below:
# "core/special/views/i18n.py"
...
def set_language(request):
...
response.set_cookie(
settings.LANGUAGE_COOKIE_NAME,
lang_code,
max_age=settings.LANGUAGE_COOKIE_AGE,
path=settings.LANGUAGE_COOKIE_PATH,
domain=settings.LANGUAGE_COOKIE_DOMAIN,
secure=settings.LANGUAGE_COOKIE_SECURE,
httponly=settings.LANGUAGE_COOKIE_HTTPONLY,
samesite=settings.LANGUAGE_COOKIE_SAMESITE,
)
# ↓ For more customizable `User` model ↓
user = request.user
if user.is_authenticated:
user.lang = lang_code
user.save()
# ↑ For more customizable `User` model ↑
# ↓ For less customizable `User` model ↓
user = request.user
if user.is_authenticated:
user.userprofile.lang = lang_code
user.userprofile.save()
# ↑ For less customizable `User` model ↑
return response
Finally, replace from django... import set_language
with from core... import set_language
in core/special/conf/urls/i18n.py
as shown below:
# "core/special/conf/urls/i18n.py"
...
# from django.views.i18n import set_language
from core.special.views.i18n import set_language