问题描述
参考官网的语言切换下拉框 模板代码例子
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设置为选中的语言,后续的地址访问就正常了,所以 语言切换功能暂时只坐在了 最初的登录页上。