首页 Django I8n多语言切换重定向问题
文章
取消

Django I8n多语言切换重定向问题

问题描述

参考官网的语言切换下拉框 模板代码例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{% load i18n %}

<form action="{% url 'set_language' %}" method="post">{% csrf_token %}
    <input name="next" type="hidden" value="{{ redirect_to }}">
    <select name="language">
        {% get_current_language as LANGUAGE_CODE %}
        {% get_available_languages as LANGUAGES %}
        {% get_language_info_list for LANGUAGES as languages %}
        {% for language in languages %}
            <option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
                {{ language.name_local }} ({{ language.code }})
            </option>
        {% endfor %}
    </select>
    <input type="submit" value="Go">
</form>

在这个例子中,Django 会在 redirect_to 变量中查找用户将要重定向的网址。

这里的redirect_to 一开始没发现 需要自己设置,所以切换时一直无法正常切换语言,因为,不显示的设置redirect_to变量,就默认为空了,而form action会调用views.i18n文件中的set_language

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def set_language(request):
    next_url = request.POST.get("next", request.GET.get("next"))
    if (
        next_url or request.accepts("text/html")
    ) and not url_has_allowed_host_and_scheme(
        url=next_url,
        allowed_hosts={request.get_host()},
        require_https=request.is_secure(),
    ):
        next_url = request.META.get("HTTP_REFERER")
        if not url_has_allowed_host_and_scheme(
            url=next_url,
            allowed_hosts={request.get_host()},
            require_https=request.is_secure(),
        ):
            next_url = "/"
    response = HttpResponseRedirect(next_url) if next_url else HttpResponse(status=204)
    if request.method == "POST":
        lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER)
        if lang_code and check_for_language(lang_code):
            if next_url:
                next_trans = translate_url(next_url, lang_code)
                if next_trans != next_url:
                    response = HttpResponseRedirect(next_trans)
            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,
            )
    return response

从该逻辑可以发现,如果next为空,最终重定向会使用 http_refer,比如原本的语言设置为 en,原来的http_refer地址 假设为 127.0.0.1:8000/en/ 那么重定向到该界面,会出现切换失败的效果

解决方式

暂时还没有一个较好的解决方式,我简陋的解决方式为定义 redirect_to 变量

通过获取当前语言字符串和请求的地址,通过切片来完成地址的截取,比如说要跳转当前地址

'redirect_to': request.path[1 + len(get_language()):]}

1
from django.utils.translation import get_language

之前的django表单提交后,会将django_language设置为选中的语言,后续的地址访问就正常了,所以 语言切换功能暂时只坐在了 最初的登录页上。

本文由作者按照 CC BY 4.0 进行授权

Django 自定义user模型 验证模块

Javascript 学习笔记