Django国旗语言切换器如何实现选择后跳转至带语言前缀的URL
核心修改思路
你当前的问题核心是表单里的next参数写死为根路径/,提交后只会跳回首页,也没有拼接选中的语言前缀。调整方案如下:
方案1:保留Django原生语言偏好记录功能(推荐)
Django自带的set_language接口会自动把用户选择的语言保存到Cookie或Session中,下次用户访问无语言前缀的根路径时会自动跳转对应语言页面,适配大部分场景,修改后代码如下:
<div class="navbar-btns ml-3"> <div class="navbar-btns-inner"> <div id="language-switcher" class="navbar-btn collapsed"> <form action="{% url 'set_language' %}" method="post"> {% csrf_token %} <!-- 存储当前路径去掉语言前缀后的基础路径 --> <input name="next_base" type="hidden" value="{{ request.path|strip_lang_prefix }}" /> <select name="language" onchange="handleLangChange(this)"> {% for language in request|get_language_info_list_ex %} <option value="{{ language.code }}" {% if language.is_current %} selected="selected"{% endif %}> <span class="flag">{{ language.flag }}</span> </option> {% endfor %} </select> </form> </div> </div> </div> <script> function handleLangChange(selectEl) { const form = selectEl.form; const selectedLang = selectEl.value; const nextBase = form.querySelector('input[name="next_base"]').value.trim(); // 拼接带语言前缀的跳转路径,避免出现双斜杠 const nextPath = nextBase ? `/${selectedLang}/${nextBase}` : `/${selectedLang}/`; // 动态生成next参数传入表单 const nextInput = document.createElement('input'); nextInput.name = 'next'; nextInput.type = 'hidden'; nextInput.value = nextPath; form.appendChild(nextInput); form.submit(); } </script>
配套配置(适配多长度语言代码)
如果你的站点有类似zh-hans这种长度超过2位的语言代码,需要新增一个自定义模板过滤器来安全移除路径前缀:
# 在你应用的templatetags目录下新建i18n_extra.py from django.conf import settings from django import template register = template.Library() @register.filter def strip_lang_prefix(path): for lang_code, _ in settings.LANGUAGES: if path.startswith(f'/{lang_code}/'): return path[len(lang_code)+2:] return path.lstrip('/')
模板顶部记得加载这个过滤器:{% load i18n_extra %}
方案2:纯前端跳转(无需提交表单)
如果不需要记录用户语言偏好,只是单纯跳转对应语言前缀的页面,可以直接简化为前端跳转逻辑,代码更轻便:
<div class="navbar-btns ml-3"> <div class="navbar-btns-inner"> <div id="language-switcher" class="navbar-btn collapsed"> <select name="language" onchange="window.location.href = `/${this.value}/${window.location.pathname.replace(/^\/[a-z-]+\/?/, '')}`"> {% for language in request|get_language_info_list_ex %} <option value="{{ language.code }}" {% if language.is_current %} selected="selected"{% endif %}> <span class="flag">{{ language.flag }}</span> </option> {% endfor %} </select> </div> </div> </div>
内容的提问来源于stack exchange,提问作者peternovak
相关产品推荐
相关产品推荐

