指南:站点地图¶
SeoSitemap 是 Django django.contrib.sitemaps.Sitemap 的一个轻量子类。它的关键特性是:每个条目的 <loc> URL 取自该条目解析出的 SEO 规范地址(canonical),因此站点地图中的 URL 始终与页面上的 rel="canonical" 保持一致。这样就从根上避免了一个常见又难以察觉的 SEO 问题:站点地图 URL 与 canonical 标签不一致。
基础站点地图¶
# sitemaps.py
from seo_suite.sitemaps import SeoSitemap
from .models import Article
class ArticleSitemap(SeoSitemap):
changefreq = "weekly"
priority = 0.8
def items(self):
return Article.objects.filter(published=True)
# urls.py
from django.contrib.sitemaps.views import sitemap
from .sitemaps import ArticleSitemap
sitemaps = {"articles": ArticleSitemap}
urlpatterns = [
path("sitemap.xml", sitemap, {"sitemaps": sitemaps}),
]
自动生成 lastmod¶
SeoSitemap 会按以下顺序检查每个条目上的属性,并把第一个找到的属性值作为 <lastmod>:
updated_at → modified → date_modified → updated → last_modified
如果这些属性都不存在,则省略 <lastmod>。常见的带有 updated_at = DateTimeField(auto_now=True) 字段的模型无需额外配置即可直接使用。
带 hreflang 替代链接的多语言站点地图¶
把 Django 内置的站点地图 i18n 属性与 SeoSitemap 结合使用:
class ArticleSitemap(SeoSitemap):
i18n = True
alternates = True
x_default = True
changefreq = "weekly"
def items(self):
return Article.objects.filter(published=True)
设置 i18n = True 后,Django 会为每个条目、每种启用的语言各生成一个 <url>。alternates = True 会为每种语言添加 <xhtml:link rel="alternate"> 条目,x_default = True 则额外添加 x-default 替代链接。
由于每个 <loc> 都来自对象的 get_seo_metadata().canonical_url(经由 SeoSitemap.location()),站点地图中的规范 URL 始终与页面上渲染出的规范 URL 保持同步。
SeoSitemap.location 的工作原理¶
对于使用了 SeoModelMixin 的条目,location() 会调用 get_seo_metadata() 并取出其中的 canonical_url。这里只使用路径和查询字符串部分,协议和主机名由 Django 的站点地图框架根据当前的 Site 对象补全。
如果条目没有 get_seo_metadata(),或者 canonical_url 未设置,location() 会回退到 Django 的默认行为,即调用 item.get_absolute_url()。
多个站点地图¶
在 urls.py 中组合多个站点地图:
from django.contrib.sitemaps.views import sitemap
from .sitemaps import ArticleSitemap, CategorySitemap, PageSitemap
sitemaps = {
"articles": ArticleSitemap,
"categories": CategorySitemap,
"pages": PageSitemap,
}
urlpatterns = [
path("sitemap.xml", sitemap, {"sitemaps": sitemaps}),
]
站点地图索引¶
对于大型站点,可以使用 Django 的 SitemapIndexSite,或者按常规方式拆分成多个站点地图即可。SeoSitemap 对条目数量没有限制。
把静态页面加入站点地图¶
对于没有对应模型的页面,写一个直接返回路径的简单站点地图即可:
from django.contrib.sitemaps import Sitemap
class StaticViewSitemap(Sitemap):
priority = 0.5
def items(self):
return ["/about/", "/contact/", "/privacy/"]
def location(self, item):
return item
只有当条目具有 get_seo_metadata() 时才需要 SeoSitemap。对于纯静态路径,Django 内置的 Sitemap 就足够了。
在 robots.txt 中指向站点地图¶
站点地图 URL 稳定下来之后,把它加入 ROBOTS_SITEMAP_URLS,爬虫就能始终通过 robots.txt 找到它:
该 URL 会以 Sitemap: 指令的形式追加到每次返回的 robots.txt 末尾,你无需修改任何版本内容。完整流程见 robots.txt 版本管理指南。