指南:基于路径的覆盖(seopath)

seopath 是一个 contrib 应用,让编辑人员可以在 Django Admin 中为任意 URL 路径覆盖 SEO 元数据,完成初始设置后无需再改代码。它适合营销页、落地页,以及所有需要在不部署的情况下调整 SEO 的 URL。


何时使用 seopath

以下场景适合使用 seopath:

  • 页面由你无法修改的第三方视图渲染。
  • 非技术人员需要在不部署代码的情况下修改页面标题或描述。
  • 你想给任意 URL 添加自定义的 robots 指令、canonical 重定向或 JSON-LD 块。
  • 同一个 URL 需要按站点或按语言输出不同的 SEO 信息。

对于你自己拥有的模型,优先使用 SeoModelMixin 或 SeoModelFieldsMixin。seopath 是以 URL 为键的覆盖机制,不能替代模型级元数据。


安装

INSTALLED_APPS = [
    "seo_suite",
    "seo_suite.contrib.seopath",
]
python manage.py migrate

在 Admin 中添加覆盖规则

在 Django Admin 中进入 SEO Suite — Path rules → SEO path rules(SEO Suite — 路径规则 → SEO 路径规则),点击 Add SEO path rule(添加 SEO 路径规则)。

字段 用途
Path URL 路径,例如 /about/ 或 /products/
Site ID 留空则应用于所有站点
Language 留空则应用于所有语言
Title 覆盖页面标题
Description 覆盖 meta description
Keywords 覆盖 meta keywords
Robots 覆盖 robots 指令
Canonical 覆盖 canonical URL
OG image 覆盖社交分享图片
Extra JSON-LD 额外的 JSON-LD 对象

路径必须精确匹配,包括末尾斜杠(如果你的站点统一使用末尾斜杠)。任何元数据字段留空,都会回退到优先级更低的来源。


特异性规则

多条规则同时匹配当前路径时,最具体的那一条胜出:

  1. site_id 和 language 都匹配:得 3 分
  2. 仅 site_id 匹配:得 2 分
  3. 仅 language 匹配:得 1 分
  4. 既无 site_id 也无 language(应用于全部):得 0 分

采用得分最高的规则,其余规则忽略。


示例:对落地页标题做 A/B 测试

为同一路径创建两条规则,然后直接在 Admin 中修改标题字段来切换,无需部署:

Path Site ID Language Title
/landing/summer/ (留空) (留空) 夏季大促——最高 5 折

标题可以随时修改,下一次请求就会使用新值。

如果启用了缓存(SEO_SUITE["CACHE_TTL"] > 0),请注意:基于路径的规则在保存时不会自动失效。你可能需要手动清除缓存,或把 TTL 设得短一些。


在模型驱动的页面上使用 seopath

seopath 运行在优先级 30,低于对象层(优先级 40)。也就是说,/articles/my-article/ 对应的 SeoPath 规则会被 Article 模型自身的 get_seo_metadata() 覆盖。

要让 SeoPath 规则压过模型,有两种办法:

  1. 改为在 SeoModelFieldsMixin 的字段列上设置(它们同样运行在优先级 40,而字段列层会合并到约定层之上)。
  2. 在视图层(优先级 50)设置:使用 SeoViewMixin 并自定义 get_seo_metadata。

如果你确实需要让基于路径的覆盖在自己的模型上压过模型字段,通常最干净的做法是添加 SeoModelFieldsMixin 字段列,让编辑人员直接在该模型的 Admin 页面上填写。


多站点与多语言配置

多站点项目中,为每个站点分别创建 SeoPath 规则:

Path Site ID Language Title
/about/ 1 关于我们
/about/ 2 关于我们的英国团队
/about/ 1 fr À propos de nous

解析器会根据当前的 site_id 和 language 选取最具体的匹配。站点 ID 由 django.contrib.sites(如已安装)、settings.SITE_ID,或自定义的 SEO_SUITE["SITE_ID_RESOLVER"] 可调用对象决定。