11đź‘Ť
Of course there is, that is the whole point of translations. You’ve confused yourself by thinking of the “default” language; something that they’ve chosen is not the default, by definition.
The Django docs explain how to set the active language for a user explicitly. You can set this on save exactly as you describe.
You probably also want to re-set this value on login, again by passing the value from the user’s profile.
3đź‘Ť
referencing to what stated in the question:
I want the user to have their own “default language” set for their
account.
The translation of a Django app with the preferred language selected by a registered user can be done with the middleware django-user-language-middleware. This allows easy translation of your Django app by looking at the selected language in the user.language
field (or what the question defines as “default language” of a user).
Usage:
-
Add a language field to your user model:
class User(auth_base.AbstractBaseUser, auth.PermissionsMixin): # ... language = models.CharField(max_length=10, choices=settings.LANGUAGES, default=settings.LANGUAGE_CODE)
-
Install the middleware from pip:
pip install django-user-language-middleware
-
Add it to your middleware class list in settings to listen to requests:
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10 ... 'user_language_middleware.UserLanguageMiddleware', ... ]
I hope this may help people landing on this question in the future.
- Celery: launch task on start
- Django: conditional expression
- Workflow using virtualenv and pip
- Upload direct to S3 or via EC2?
- Deploying existing Django app on Heroku
0đź‘Ť
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 toUser
model following one of two ways(my answer) to create customUser
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
- Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it
- Do I need to close connection in mongodb?
- Using urls names in views