Django 4.0.6多语言站点地图重复默认语言URL异常
解决Django 4.0.6多语言站点地图URL重复问题
问题现象
- 单默认语言(英文)环境下,站点地图功能正常
- 启用i18n多语言配置后,站点地图未生成正确的荷兰语URL,反而将英文URL重复标记为荷兰语地址
- 生成的站点地图片段示例:
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml"> <url> <loc>http://lettergun.com/en/</loc> <lastmod>2022-07-04</lastmod> <changefreq>daily</changefreq> <priority>0.5</priority> <xhtml:link rel="alternate" hreflang="en" href="http://lettergun.com/en/" /> <xhtml:link rel="alternate" hreflang="nl" href="http://lettergun.com/en/" /> <xhtml:link rel="alternate" hreflang="x-default" href="http://lettergun.com/" /> </url> ...
问题核心原因
直接在Sitemap子类中用location = reverse_lazy("xxx")赋值时,reverse_lazy会在类加载阶段就基于默认语言生成URL,后续Sitemap的多语言逻辑无法动态替换语言前缀,导致所有语言版本都复用了默认语言的URL。
解决方案
重写Sitemap类的location方法,在方法内针对当前处理的语言动态生成对应URL:
修改sitemaps.py代码如下:
from datetime import datetime from django.contrib.sitemaps import Sitemap from django.urls import reverse from django.utils.translation import activate class LettergunSitemap(Sitemap): i18n = True languages = ["en", "nl"] alternates = True x_default = True changefreq = "daily" priority = 0.5 lastmod = datetime.strptime(LAST_MOD, "%Y-%m-%d") def location(self, item): # 动态激活当前语言并生成对应URL activate(self.language) return reverse(self.view_name) class Home(LettergunSitemap): view_name = "base:home" def items(self): return ["item"] class Contact(LettergunSitemap): view_name = "base:contact" def items(self): return ["item"] class DemoRequest(LettergunSitemap): view_name = "base:demo" def items(self): return ["item"]
额外验证步骤
- 确保
settings.py中多语言配置正确:
LANGUAGE_CODE = 'en' LANGUAGES = [ ('en', 'English'), ('nl', 'Nederlands'), ] USE_I18N = True LOCALE_PATHS = [ BASE_DIR / 'locale', ]
- 确认
urls.py中i18n_patterns正确包裹了需要国际化的路由 - 清除Django缓存后重新访问站点地图
修改完成后,站点地图会为每个语言生成正确的URL,荷兰语的<xhtml:link>标签将指向http://lettergun.com/nl/这类符合预期的路径。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

