Django中使用Sitemap的方法讲解及示例
Django附带了一个高级站点地图生成框架来创建站点地图XML文件。
概述¶
站点地图是您网站上的一个 XML 文件,用于告知搜索引擎索引器您的网页更改频率以及某些网页相对于您网站上的其他网页的“重要性”。此信息可帮助搜索引擎将您的网站编入索引。
Django站点地图框架通过允许您在Python代码中表达此信息来自动创建此XML文件。
它的工作方式很像Django的联合框架。要创建站点地图,请编写一个sitemap类,并在网址中指向该类。
安装¶
要安装站点地图应用,请按以下步骤操作:
- 添加到您的
INSTALLED_APPS
设置。'django.contrib.sitemaps'
- 确保
TEMPLATES
设置包含其选项设置为 的后端。默认情况下,它在那里,因此您只需要在更改该设置时更改此设置即可。INSTALLED_APPS = [ 'category.apps.CategoryConfig',#分类 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.sitemaps'#sitemaps ]
- 确保已安装
站点框架
。
(注意:站点地图应用程序不会安装任何数据库表。它需要进入INSTALLED_APPS
的唯一原因是 Loader()
模板加载程序可以找到默认模板。
初始化¶
views.
sitemap
(请求,站点地图,部分=无,template_name='站点地图.xml',content_type='application/xml')¶
要在 Django 网站上激活站点地图生成,请将此行添加到项目/urls.py:
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
位于/content/sitemap.xml
,它可能仅引用以/content/
开头的网址。
站点地图视图需要一个额外的必需参数:。 应该是将短节标签(例如,{'sitemaps': sitemaps}
).站点地图将映射到其sitemaps
类(例如,blog
或news
)的字典。它还可以映射到sitemaps类的BlogSitemap或NewsSitemap
实例(例如,BlogSitemap(some_var)
)。
Sitemap
类¶
sitemaps类是一个 Python 类,表示站点地图中条目的“部分”。例如,一个sitemaps类可以表示您博客的所有条目,而另一个站点地图类可以表示事件日历中的所有事件。
在最简单的情况下,所有这些部分都被归为一个 ,但也可以使用该框架生成一个站点地图索引,该索引引用单个站点地图文件,每个部分一个。(请参阅下面的创建站点地图索引。sitemap.xml
站点地图
类必须为 子类 。它们可以位于代码库中的任何地方。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
分别是对应于 和 元素的类属性。它们可以作为函数调用,就像示例中的lastmod
一样。<changefreq>
<priority>
items()
是返回一个或多个对象序列的方法。返回的对象将传递到与站点地图属性(位置
、上一步
、changefreq
和优先级
)对应的任何可调用方法。QuerySet
lastmod
应返回日期时间
。- 此示例中没有
定位
方法,但您可以提供该方法以指定对象的 URL。默认情况下,location()
调用每个对象并返回结果。get_absolute_url()
Sitemap
类引用¶
类 Sitemap
¶
类可以定义以下方法/属性:Sitemap
items
¶
必填。返回一个或多个对象序列的方法。框架不关心它们是什么类型的对象;重要的是这些对象被传递到 location()
、lastmod()
、changefreq()
和 priority()
方法。QuerySet
location
¶
自选。方法或属性。
如果它是一个方法,它应该返回 items()
返回的给定对象的绝对路径。
如果它是一个属性,则其值应为一个字符串,表示用于 items()
返回的每个对象的绝对路径。
在这两种情况下,“绝对路径”都表示不包含协议或域的 URL。例子:
- 好:
'/foo/bar/'
- 坏:
'example.com/foo/bar/'
- 坏:
'https://example.com/foo/bar/'
如果未提供位置
,框架将在 items()
返回的每个对象上调用该方法。get_absolute_url()
要指定 除 以外的协议,请使用协议
。'http'
lastmod
¶
自选。方法或属性。
如果它是一个方法,它应该采用一个参数 - 由 items()
返回的对象 - 并将该对象的上次修改日期/时间作为日期时间
返回。
如果它是一个属性,则其值应为日期时间,
表示 items()
返回的每个对象的上次修改日期/时间。
如果站点地图中的所有项目都具有 lastmod
,则 views.sitemap()
生成的站点地图将具有与 latest 相同的标头。您可以激活 ConditionalGetMiddleware
,使 Django 对带有标头的请求做出适当的响应,如果站点地图没有更改,则会阻止发送站点地图。Last-Modified
lastmod
If-Modified-Since
paginator
¶
自选。
此属性返回 items()
的分页器
。如果您批量生成站点地图,则可能需要将其覆盖为缓存属性,以避免多次调用。items()
changefreq
¶
自选。方法或属性。
如果它是一个方法,它应该采用一个参数 - 由 items()
返回的对象 - 并将该对象的更改频率作为字符串返回。
如果它是一个属性,则其值应为一个字符串,表示 items()
返回的每个对象的更改频率。
无论您使用方法还是属性,changefreq
的可能值为:
'always'
'hourly'
'daily'
'weekly'
'monthly'
'yearly'
'never'
priority
¶
自选。方法或属性。
如果它是一个方法,它应该采用一个参数 - 由 items()
返回的对象 - 并将该对象的优先级作为字符串或浮点数返回。
如果它是一个属性,则其值应为字符串或浮点数,表示 items()
返回的每个对象的优先级。
优先级
的示例值:、 。页面的默认优先级为 。有关详细信息,请参阅 sitemaps.org 文档。0.4
1.0
0.5
protocol
¶
自选。
此属性定义站点地图中网址的协议( 或 )。如果未设置,则使用请求站点地图时使用的协议。如果站点地图是在请求上下文之外构建的,则默认值为 。'http'
'https'
'http'
自版本 4.0 起已弃用:在 Django 5.0 中,在请求上下文之外构建的站点地图的默认协议将从 更改为 。'http'
'https'
limit
¶
自选。
此属性定义站点地图的每个网页上包含的最大网址数。其值不应超过默认值 ,这是站点地图协议中允许的上限。50000
i18n
¶
自选。
一个布尔属性,用于定义是否应使用您的所有语言
生成此站点地图的 URL。缺省值为 。False
languages
¶
自选。
启用 i18n
时用于生成备用链接的语言代码序列。默认为语言
。
alternates
¶
自选。
布尔属性。当与 i18n
结合使用时,生成的 URL 将具有一个使用 hreflang 属性指向其他语言版本的备用链接列表。缺省值为 。False
x_default
¶
自选。
布尔属性。当备用链接生成的备用
链接将包含值为 LANGUAGE_CODE
的回退条目时。缺省值为 。True
hreflang="x-default"
False
快捷方式¶
站点地图框架为常见情况提供了一个便利类:
类 (info_dict, 优先级 = 无, 更改频率 = 无, 协议 = 无GenericSitemap
)¶
django.contrib.sitemaps.GenericSitemap
类允许您通过向站点地图传递一个必须至少包含条目的字典来创建站点地图。此查询集将用于生成站点地图的项。它还可能具有一个条目,该条目为从 中检索到的对象指定日期字段。这将用于生成的站点地图中的 lastmod
属性。queryset
date_field
queryset
优先级
、changefreq
和协议
关键字参数允许为所有 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'),
]
静态视图的站点地图¶
通常,您希望搜索引擎爬网程序对既不是对象详细信息页面也不是平面页面的视图编制索引。解决方案是在站点地图的方法中显式列出这些视图的 URL 名称,并调用 reverse()。
例如:items
location
# 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.xml
sitemap-flatpages.xml
sitemap-blog.xml
sitemaps
如果您的某个站点地图的网址超过 50,000 个,则应创建一个索引文件。在这种情况下,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'),
]
模板定制¶
如果您希望对网站上可用的每个站点地图或站点地图索引使用不同的模板,则可以通过 URLconf 将参数传递给 和 视图来指定该模板:template_name
sitemap
index
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
实例,允许您在渲染之前轻松自定义响应数据。有关更多详细信息,请参阅模板响应文档。
指数¶
该变量是每个站点地图的绝对网址列表。sitemaps
网站地图¶
该变量是应显示在站点地图中的网址列表。每个网址都公开站点地图
类中定义的属性:urlset
alternates
changefreq
item
lastmod
location
priority
启用 i18n
和备用项时,
该属性可用。它是每个 URL 的其他语言版本(包括可选的x_default
回退)的列表。每个备选方案都是一个带有 和 键的字典。alternates
location
lang_code
alternates
已为每个网址添加了该属性,以便更灵活地自定义模板,例如 Google 新闻站点地图。假设站点地图的 items()
将返回包含项的列表,而类似如下的字段将生成与 Google 新闻兼容的站点地图:item
publication_data
tags
<?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>
平安谷歌¶
当您的站点地图发生变化时,您可能希望“ping”Google,以便告知它重新索引您的网站。站点地图框架提供了一个功能来做到这一点:django.contrib.sitemaps.ping_google()
。
ping_google
(sitemap_url=无,ping_url=PING_URL,sitemap_uses_https=真)¶
ping_google
采用以下可选参数:
sitemap_url
- 您网站站点地图的绝对路径(例如,)。'/sitemap.xml'
如果未提供此参数,则会在网址中对命名的网址执行反向查找,然后(无需进一步参数)自动确定站点地图网址。
ping_google
'django.contrib.sitemaps.views.index'
'django.contrib.sitemaps.views.sitemap'
ping_url
- 默认为谷歌的Ping工具:https://www.google.com/webmasters/tools/ping。sitemap_uses_https
- 设置为如果您的网站使用而不是 .False
http
https
ping_google()
会在无法确定您的站点地图网址时引发异常。django.contrib.sitemaps.SitemapNotFound
首先向谷歌注册!
ping_google()
命令仅在您向 Google Search Console 注册您的网站时才有效。
调用ping_google()
的一种有用方法是从模型的方法:save()
from django.contrib.sitemaps import ping_google
class Entry(models.Model):
# ...
def save(self, force_insert=False, force_update=False):
super().save(force_insert, force_update)
try:
ping_google()
except Exception:
# Bare 'except' because we could get a variety
# of HTTP-related exceptions.
pass
然而,更有效的解决方案是从cron脚本或其他一些计划任务调用ping_google()。
该函数向Google的服务器发出HTTP请求,因此您可能不希望每次调用时都引入该网络开销。save()