如何使用i18n切换器将`LANGUAGE_CODE`保存到数据库中,以便在Django中不会在不同的浏览器中更改语言?

12
有没有办法在点击按钮(发送请求)时动态地更改settings.py中的LANGUAGE_CODE变量的值?
我希望用户能够为他们的账户设置自己的“默认语言”。
目前,用户可以使用下拉列表选择他们喜欢的语言,网站会完美地进行翻译,并且由于Django会获取浏览器的语言,用户在同一浏览器中重新打开网站时无需重新选择语言。
但是,当他们从另一个浏览器打开网站时,默认语言再次变为“英语”,这是因为settings.py中的LANGUAGE_CODE变量被设置为en-us。
所以我想做的是让每个用户都有选择他们所需语言作为默认语言的选项。我想通过创建另一个(类似的)下拉列表,要求用户选择他们想要的语言作为“默认语言”,然后点击“保存”按钮,在保存时将LANGUAGE_CODE的值更改为用户选择的值(即动态更改)。但是我不知道如何动态地更改LANGUAGE_CODE的值。
此外,这种方法还存在一个问题。即使我能够动态更改LANGUAGE_CODE变量,网站的默认语言也会成为所有用户的选择语言,而不仅仅是那个特定更改它的用户,根据Django的文档:

LANGUAGE_CODE:

  • 如果没有使用区域设置中间件,它决定向所有用户提供哪种翻译。
我进行了大量研究,但找不到适合我的解决方案。我对国际化非常陌生,请帮忙。
3个回答

11

当然有,这就是翻译的全部意义。你认为“默认”语言是一种误解,根据定义,他们选择的东西不是默认的。

Django 文档中说明了如何显式地设置活动语言。您可以在保存时像您描述的那样设置它。

您可能还希望通过从用户配置文件传递值再次在登录时重新设置此值。


非常感谢您的回答。这正是我在寻找的:D - Yoshita Arora

3

参考问题陈述:

我希望用户能够设置自己账户的“默认语言”。

使用中间件django-user-language-middleware,可以根据注册用户选择的首选语言轻松翻译Django应用程序。这样可以通过查看用户的user.language字段(或问题定义的用户“默认语言”)来进行Django应用程序的翻译。

用法:

  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',
        ...
    ]
    
我希望这篇文章能帮助未来遇到这个问题的人们。

2
只有在从头开始创建新项目或应用程序时才能正常工作,因为AbstractBaseUser模型需要在第一次迁移之前定义。如果您无法重置迁移和数据库,则必须覆盖中间件。 - Tobit
注释可能有点老,但是如果你被标准用户卡住了,你总是可以将其移动到“UserProfile”,但始终从“AbstractUser”开始! - nitsujri
@laura-barluzzi,现在存储语言信息在Django会话中已经不推荐使用了,有没有可能更新一下这个非常有用的包呢? - Skratt

0
你可以使用i18n switchersettings.py中更改和保存LANGUAGE_CODE,这样即使你使用不同的浏览器,语言也不会改变。
首先,你需要完成以下3个步骤:
  1. User模型中添加lang字段,根据两种方式(我的答案)之一创建自定义User模型。*我推荐更可定制的方式(我的答案)而不是较不可定制的方式(我的答案)

    lang = models.CharField(max_length=20, blank=True)
    
  2. 按照我的答案设置Djnago的翻译(英语和法语)。

  3. 分别按照我的答案我的答案Django和/或Django Admin创建。

接下来,创建special/middleware/special/views/special/conf/urls/文件夹,并在其中分别添加__init__.py(空文件),然后将django/middleware/locale.pydjango/views/i18n.pydjango/conf/urls/i18n.py中的locale.pyi18n.pyi18n.py复制到您的虚拟环境中的special/middleware/special/views/special/conf/urls/文件夹中,如下所示:
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

然后,在core/settings.py中,将`'django...LocaleMiddleware'`替换为`'core...LocaleMiddleware'`,如下所示:
# "core/settings.py"

MIDDLEWARE = [
    ...
    "django.contrib.sessions.middleware.SessionMiddleware",
    # 'django.middleware.locale.LocaleMiddleware',
    'core.special.middleware.locale.LocaleMiddleware',
    "django.middleware.common.CommonMiddleware",
]

然后,在core/urls.py中将path(... include("django..."))替换为path(... include("core...")),如下所示:

# "core/urls.py"

urlpatterns += [
    # path("i18n/", include("django.conf.urls.i18n"))
    path("i18n/", include("core.special.conf.urls.i18n"))
]

然后,按照下面的示例将以下代码添加到core/special/middleware/locale.py中:
# "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()

然后,按照下面的示例将以下代码添加到core/special/views/i18n.py中:
# "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

最后,在`core/special/conf/urls/i18n.py`中,将from django... import set_language替换为from core... import set_language,如下所示。
# "core/special/conf/urls/i18n.py"

...
# from django.views.i18n import set_language
from core.special.views.i18n import set_language

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接