网站地图框架¶
Django 附带了一个高级网站地图生成框架,用于创建 网站地图 XML 文件。
概述¶
网站地图是网站上的一个 XML 文件,它告诉搜索引擎索引器你的页面更改的频率以及某些页面相对于网站上其他页面的“重要性”。这些信息有助于搜索引擎索引你的网站。
Django 网站地图框架通过让你用 Python 代码表示这些信息,自动创建此 XML 文件。
它的工作方式与 Django 的 联合框架 非常相似。要创建网站地图,请编写一个 Sitemap
类,并在你的 URLconf 中指向它。
安装¶
要安装网站地图应用程序,请按照以下步骤操作
- 将
'django.contrib.sitemaps'
添加到你的INSTALLED_APPS
设置中。 - 确保你的
TEMPLATES
设置包含一个DjangoTemplates
后端,其APP_DIRS
选项设置为True
。默认情况下它就在那里,因此只有在你更改了该设置时才需要更改此设置。 - 确保已安装
sites 框架
。
(注意:站点地图应用程序不会安装任何数据库表。它需要进入 INSTALLED_APPS
的唯一原因是,Loader()
模板加载器可以找到默认模板。)
初始化¶
-
views.
sitemap
(request, sitemaps, section=None, template_name='sitemap.xml', content_type='application/xml')¶
要在 Django 网站上激活站点地图生成,请将此行添加到 URLconf
from django.contrib.sitemaps.views import sitemap
path(
"sitemap.xml",
sitemap,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.sitemap",
)
这告诉 Django 在客户端访问 /sitemap.xml
时构建站点地图。
网站地图文件的文件名不重要,但位置很重要。搜索引擎只会在当前 URL 级别及以下级别为网站地图中的链接编制索引。例如,如果 sitemap.xml
位于根目录中,它可能会引用网站中的任何 URL。但是,如果网站地图位于 /content/sitemap.xml
,它可能只引用以 /content/
开头的 URL。
网站地图视图需要一个额外的必需参数:{'sitemaps': sitemaps}
。 sitemaps
应该是一个字典,它将一个简短的节标签(例如,blog
或 news
)映射到其 Sitemap
类(例如,BlogSitemap
或 NewsSitemap
)。它还可以映射到 Sitemap
类的实例(例如,BlogSitemap(some_var)
)。
Sitemap
类¶
Sitemap
类是一个 Python 类,它表示网站地图中条目的“节”。例如,一个 Sitemap
类可以表示博客的所有条目,而另一个类可以表示活动日历中的所有活动。
在最简单的情况下,所有这些节都会合并到一个 sitemap.xml
中,但也可以使用框架生成引用单个网站地图文件的网站地图索引,每个节一个。(请参阅下面的 创建网站地图索引。)
Sitemap
类必须是 django.contrib.sitemaps.Sitemap
的子类。它们可以存在于代码库中的任何位置。
示例¶
假设您有一个博客系统,其中包含一个 Entry
模型,并且您希望您的网站地图包含指向您各个博客文章的所有链接。以下是您的网站地图类可能的样子
from django.contrib.sitemaps import Sitemap
from blog.models import Entry
class BlogSitemap(Sitemap):
changefreq = "never"
priority = 0.5
def items(self):
return Entry.objects.filter(is_draft=False)
def lastmod(self, obj):
return obj.pub_date
注意
changefreq
和priority
是分别对应于<changefreq>
和<priority>
元素的类属性。它们可以作为函数进行调用,就像lastmod
在示例中一样。items()
是一个返回 序列 或对象QuerySet
的方法。返回的对象将传递给对应于网站地图属性的任何可调用方法(location
、lastmod
、changefreq
和priority
)。lastmod
应返回datetime
。- 此示例中没有
location
方法,但你可以提供该方法以指定对象的 URL。默认情况下,location()
会对每个对象调用get_absolute_url()
并返回结果。
Sitemap
类参考¶
-
class
Sitemap
¶ Sitemap
类可以定义以下方法/属性-
items
¶ 必需。返回 序列 或对象的
QuerySet
的方法。框架并不关心它们是什么类型的对象;重要的是这些对象会传递给location()
、lastmod()
、changefreq()
和priority()
方法。
-
位置
¶ 可选。方法或属性。
如果它是方法,它应返回
items()
返回的给定对象的绝对路径。如果它是属性,其值应为一个字符串,表示
items()
返回的每个对象的绝对路径。在这两种情况下,“绝对路径”表示不包含协议或域的 URL。示例
- 好:
'/foo/bar/'
- 差:
'example.com/foo/bar/'
- 差:
'https://example.com/foo/bar/'
如果未提供
位置
,框架将对items()
返回的每个对象调用get_absolute_url()
方法。要指定
'http'
以外的协议,请使用协议
。- 好:
-
上次修改
¶ 可选。方法或属性。
如果它是方法,它应采用一个参数 -
items()
返回的对象 - 并返回该对象的上次修改日期/时间,格式为datetime
。如果它是属性,其值应为
datetime
,表示items()
返回的每个对象的上次修改日期/时间。如果网站地图中的所有项都具有
lastmod
,则由views.sitemap()
生成的网站地图将具有等于最新lastmod
的Last-Modified
头。您可以激活ConditionalGetMiddleware
,以便让 Django 适当地响应带有If-Modified-Since
头的请求,该头将阻止发送未更改的网站地图。
-
changefreq
¶ 可选。方法或属性。
如果它是一个方法,它应该接受一个参数——一个由
items()
返回的对象——并返回该对象的更改频率,作为字符串。如果它是一个属性,其值应为一个字符串,表示由
items()
返回的每个对象的更改频率。无论您使用的是方法还是属性,
changefreq
的可能值为'always'
'hourly'
'daily'
'weekly'
'monthly'
'yearly'
'never'
-
priority
¶ 可选。方法或属性。
如果它是一个方法,它应该采用一个参数——由
items()
返回的对象——并返回该对象的优先级,可以是字符串或浮点数。如果它是一个属性,它的值应该是表示由
items()
返回的每个对象的优先级的字符串或浮点数。priority
的示例值:0.4
、1.0
。页面的默认优先级为0.5
。有关更多信息,请参阅 sitemaps.org 文档。
-
protocol
¶ 可选。
此属性定义站点地图中 URL 的协议(
'http'
或'https'
)。如果未设置,则使用请求站点地图的协议。如果在请求的上下文中外部构建站点地图,则默认值为'https'
。在 Django 5.0 中更改在较旧版本中,在请求的上下文中外部构建的站点地图的默认协议为
'http'
。
-
alternates
¶ 可选。
一个布尔属性。与
i18n
结合使用时,生成的 URL 将分别具有一个备用链接列表,指向使用 hreflang 属性 的其他语言版本。默认值为False
。
-
x_default
¶ 可选。
一个布尔属性。当
True
时,由alternates
生成的备用链接将包含一个hreflang="x-default"
回退项,其值为LANGUAGE_CODE
。默认值为False
。
-
get_latest_lastmod
()¶ 可选。返回
lastmod
返回的最新值的方法。此函数用于将lastmod
属性添加到 Sitemap 索引上下文变量。默认情况下,
get_latest_lastmod()
返回- 如果
lastmod
是一个属性:lastmod
。 - 如果
lastmod
是一个方法:通过使用Sitemap.items()
返回的所有项调用此方法返回的最新lastmod
。
- 如果
-
get_languages_for_item
(item)¶ - Django 4.2 中的新增功能。
可选。返回显示该项的语言代码序列的方法。默认情况下,
get_languages_for_item()
返回languages
。
-
快捷方式¶
Sitemap 框架为常见情况提供了一个便捷类
-
类
GenericSitemap
(info_dict, priority=无, changefreq=无, protocol=无)¶ 通过向
django.contrib.sitemaps.GenericSitemap
类传递一个至少包含一个queryset
条目的字典,你可以创建一个站点地图。此查询集将用于生成站点地图的项目。它还可以有一个date_field
条目,该条目指定从queryset
检索的对象的日期字段。这将用于生成站点地图中的lastmod
属性和get_latest_lastmod()
方法。关键字参数
priority
、changefreq
和protocol
允许为所有 URL 指定这些属性。
示例¶
下面是一个使用 GenericSitemap
的 URLconf 示例
from django.contrib.sitemaps import GenericSitemap
from django.contrib.sitemaps.views import sitemap
from django.urls import path
from blog.models import Entry
info_dict = {
"queryset": Entry.objects.all(),
"date_field": "pub_date",
}
urlpatterns = [
# some generic view using info_dict
# ...
# the sitemap
path(
"sitemap.xml",
sitemap,
{"sitemaps": {"blog": GenericSitemap(info_dict, priority=0.6)}},
name="django.contrib.sitemaps.views.sitemap",
),
]
静态视图的站点地图¶
通常,您希望搜索引擎爬虫索引既不是对象详细页面也不是扁平页面的视图。解决方案是在 items
中明确列出这些视图的 URL 名称,并在站点地图的 location
方法中调用 reverse()
。例如
# sitemaps.py
from django.contrib import sitemaps
from django.urls import reverse
class StaticViewSitemap(sitemaps.Sitemap):
priority = 0.5
changefreq = "daily"
def items(self):
return ["main", "about", "license"]
def location(self, item):
return reverse(item)
# urls.py
from django.contrib.sitemaps.views import sitemap
from django.urls import path
from .sitemaps import StaticViewSitemap
from . import views
sitemaps = {
"static": StaticViewSitemap,
}
urlpatterns = [
path("", views.main, name="main"),
path("about/", views.about, name="about"),
path("license/", views.license, name="license"),
# ...
path(
"sitemap.xml",
sitemap,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.sitemap",
),
]
创建站点地图索引¶
-
views.
index
(request, sitemaps, template_name='sitemap_index.xml', content_type='application/xml', sitemap_url_name='django.contrib.sitemaps.views.sitemap')¶
站点地图框架还具有创建站点地图索引的能力,该索引引用各个站点地图文件,每个文件对应于 sitemaps
字典中定义的一个部分。使用上的唯一区别是
- 您在 URLconf 中使用两个视图:
django.contrib.sitemaps.views.index()
和django.contrib.sitemaps.views.sitemap()
。 django.contrib.sitemaps.views.sitemap()
视图应采用section
关键字参数。
以下是上述示例中相关的 URLconf 行的显示方式
from django.contrib.sitemaps import views
urlpatterns = [
path(
"sitemap.xml",
views.index,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.index",
),
path(
"sitemap-<section>.xml",
views.sitemap,
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.sitemap",
),
]
这将自动生成一个引用 sitemap-flatpages.xml
和 sitemap-blog.xml
的 sitemap.xml
文件。Sitemap
类和 sitemaps
字典根本不会更改。
如果所有站点地图都有 Sitemap.get_latest_lastmod()
返回的 lastmod
,则站点地图索引将具有等于最新 lastmod
的 Last-Modified
头。
如果您的某个站点地图有超过 50,000 个 URL,则应创建一个索引文件。在这种情况下,Django 会自动对站点地图进行分页,并且索引将反映这一点。
如果您没有使用香草站点地图视图(例如,如果它用缓存装饰器包装),则必须为您的站点地图视图命名,并将 sitemap_url_name
传递给索引视图
from django.contrib.sitemaps import views as sitemaps_views
from django.views.decorators.cache import cache_page
urlpatterns = [
path(
"sitemap.xml",
cache_page(86400)(sitemaps_views.index),
{"sitemaps": sitemaps, "sitemap_url_name": "sitemaps"},
),
path(
"sitemap-<section>.xml",
cache_page(86400)(sitemaps_views.sitemap),
{"sitemaps": sitemaps},
name="sitemaps",
),
]
模板定制¶
如果您希望为您的网站上可用的每个站点地图或站点地图索引使用不同的模板,则可以通过向 sitemap
和 index
视图通过 URLconf 传递 template_name
参数来指定它
from django.contrib.sitemaps import views
urlpatterns = [
path(
"custom-sitemap.xml",
views.index,
{"sitemaps": sitemaps, "template_name": "custom_sitemap.html"},
name="django.contrib.sitemaps.views.index",
),
path(
"custom-sitemap-<section>.xml",
views.sitemap,
{"sitemaps": sitemaps, "template_name": "custom_sitemap.html"},
name="django.contrib.sitemaps.views.sitemap",
),
]
这些视图返回 TemplateResponse
实例,它允许您在呈现之前轻松定制响应数据。有关更多详细信息,请参阅 TemplateResponse 文档。
索引¶
变量 sitemaps
是一个包含 location
和 lastmod
属性的每个网站地图的对象列表。每个 URL 暴露以下属性
location
:网站地图的位置(url 和页面)。lastmod
:由get_latest_lastmod()
方法填充,适用于每个网站地图。
网站地图¶
变量 urlset
是应出现在网站地图中的 URL 列表。每个 URL 暴露 Sitemap
类中定义的属性
alternates
changefreq
item
lastmod
location
priority
当启用 i18n
和 alternates
时,alternates
属性可用。它是一个其他语言版本列表,包括每个 URL 的可选 x_default
回退。每个备用都是一个包含 location
和 lang_code
键的字典。
为每个 URL 添加了 item
属性,以便更灵活地自定义模板,例如 Google 新闻站点地图。假设 Sitemap 的 items()
将返回一个包含 publication_data
和 tags
字段的项列表,如下所示,将生成一个与 Google 新闻兼容的站点地图
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
{% spaceless %}
{% for url in urlset %}
<url>
<loc>{{ url.location }}</loc>
{% if url.lastmod %}<lastmod>{{ url.lastmod|date:"Y-m-d" }}</lastmod>{% endif %}
{% if url.changefreq %}<changefreq>{{ url.changefreq }}</changefreq>{% endif %}
{% if url.priority %}<priority>{{ url.priority }}</priority>{% endif %}
<news:news>
{% if url.item.publication_date %}<news:publication_date>{{ url.item.publication_date|date:"Y-m-d" }}</news:publication_date>{% endif %}
{% if url.item.tags %}<news:keywords>{{ url.item.tags }}</news:keywords>{% endif %}
</news:news>
</url>
{% endfor %}
{% endspaceless %}
</urlset>