[Solved]-How to save `LANGUAGE_CODE` to database with i18n switcher so that the language is not changed in different browsers in Django?

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:

  1. 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)
    
  2. Install the middleware from pip:

    pip install django-user-language-middleware

  3. 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.

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:

  1. 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)
    
  2. Set translation(English and French) in Djnago following my answer.

  3. 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

Leave a comment