[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