站点地图是网站上的XML文件,它告诉搜索引擎索引器您的页面更改的频率以及某些页面与您网站上其他页面的相关程度。 这些信息有助于搜索引擎索引您的网站。 有关站点地图的更多信息,请参阅sitemaps.org网站。
Django站点地图框架通过让你用Python代码表达这些信息来自动创建这个XML文件。 它与Django的整合框架非常相似。 要创建一个网站地图,
只需编写一个Sitemap类并指向它在URLconf中。
安装
要安装站点地图应用程序,请按照下列步骤操作:
- 将“django.contrib.sitemaps”添加到您的INSTALLED_APPS设置中。
- 确保您的TEMPLATES设置包含一个DjangoTemplates后端,其APP_DIRS选项设置为True。 它默认在那里,所以如果你改变了这个设置,你只需要改变它。
- 确保你已经安装了网站框架。
初始化
要在您的Django站点上激活站点地图生成,请将此行添加到您的URLconf中:
from django.contrib.sitemaps.views import sitemap
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap')
这告诉Django在客户端访问/sitemap.xml时建立一个站点地图。 网站地图文件的名称并不重要,但位置是。 搜索引擎只会将您网站地图中的链接编入当前网址级别及以下。 例如,如果sitemap.xml存在于您的根目录中,它可能会引用您网站中的任何URL。 但是,如果您的站点地图位于/content/sitemap.xml,则它可能只会引用以/ content /开头的URL。
站点地图视图需要额外的必需参数:{'sitemaps':sitemaps}。 站点地图应该是一个将短节标签(例如博客或新闻)映射到其Sitemap类(例如BlogSitemap或NewsSitemap)的词典。 它也可以映射到Sitemaps类的一个实例(例如BlogSitemap(some_var))。
网站地图类
Sitemaps类是一个简单的Python类,代表您的站点地图中的一部分条目。 例如,一个Sitemaps类可以代表您Weblog的所有条目,而另一个可以代表您的事件日历中的所有事件。
在最简单的情况下,所有这些部分都集中到一个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()只是一个返回对象列表的方法。 返回的对象将传递给与sitemap属性(location,lastmod,changefreq和priority)相对应的任何可调用方法。
-
lastmod应该返回一个Python日期时间对象。
-
在这个例子中没有位置方法,但是您可以提供它以指定对象的URL。 默认情况下,location()在每个对象上调用get_absolute_url()并返回结果。
Sitemap类参考
Sitemap类可以定义以下方法/属性:
items
必须的。 一种返回对象列表的方法。 框架不关心它们是什么类型的对象; 重要的是这些对象传递给location(),lastmod(),changefreq()和priority()方法。
location
可选的。 方法或属性。 如果它是一个方法,它应该返回由items()返回的给定对象的绝对路径。 如果它是一个属性,它的值应该是一个字符串,表示由items()返回的每个对象的绝对路径。
在这两种情况下,绝对路径都是指不包含协议或域的URL。 例子:
- Good: '/foo/bar/'
- Bad: 'example.com/foo/bar/'
- Bad: 'http://example.com/foo/bar/'
如果未提供位置,则框架将调用由items()返回的每个对象上的get_absolute_url()方法。 要指定除http以外的协议,请使用协议。
lastmod
可选的。 方法或属性。 如果它是一种方法,它应该采用一个参数 - 一个由items()返回的对象 - 并返回该对象的最后修改日期/时间,作为Python datetime.datetime对象。
如果它是一个属性,它的值应该是一个Python datetime.datetime对象,表示由items()返回的每个对象的最后修改日期/时间。 如果站点地图中的所有项目都有lastmod,则由views.sitemap()生成的站点地图将具有与最新的lastmod相同的Last-Modified标头。
您可以激活ConditionalGetMiddleware以使Django可以正确响应具有If-Modified-Since标头的请求,这将防止发送站点地图(如果它没有更改)。
changefreq
可选的。 方法或属性。 如果它是一个方法,它应该采用一个参数 - 一个由items()返回的对象 - 并返回该对象的更改频率,如Python字符串。 如果它是一个属性,它的值应该是一个字符串,表示由items()返回的每个对象的变化频率。
changefreq的可能值,不管您是使用方法还是属性,都是:
- 'always'
- 'hourly'
- 'daily'
- 'weekly'
- 'monthly'
- 'yearly'
- 'never'
优先级
可选的。 方法或属性。 如果它是一个方法,它应该采用一个参数 - 一个由items()返回的对象 - 并返回该对象的优先级,如字符串或浮点数。
如果它是一个属性,它的值应该是一个字符串或浮点数,表示由items()返回的每个对象的优先级。 优先级的示例值:0.4,1.0。 一个页面的默认优先级是0.5。
有关更多信息,请参阅sitemaps.org文档。
协议
可选的。 该属性定义站点地图中URL的协议(http或https)。 如果未设置,则使用请求站点地图的协议。 如果站点地图是在请求的上下文之外构建的,则默认为http。
国际化
可选的。 一个布尔属性,用于定义是否应该使用所有语言生成此站点地图的URL。 默认值是False。
快捷键
站点地图框架为常见案例提供了便利类 - django.contrib.syndication.GenericSitemap
django.contrib.sitemaps.GenericSitemap类允许您通过传递一个包含至少一个查询集条目的字典来创建站点地图。 该查询集将用于生成站点地图的项目。 它也可能有一个date_field条目,它指定从查询集中检索的对象的日期字段。
这将用于生成的站点地图中的lastmod属性。 您也可以将优先级和changefreq关键字参数传递给GenericSitemap构造函数,以为所有URL指定这些属性。
例如
Here's an example of a URLconf using `GenericSitemap`:
from django.conf.urls import url
from django.contrib.sitemaps import GenericSitemap
from django.contrib.sitemaps.views import sitemap
from blog.models import Entry
info_dict = {
'queryset': Entry.objects.all(),
'date_field': 'pub_date',
}
urlpatterns = [
# some generic view using info_dict
# ...
# the sitemap
url(r'^sitemap\.xml$', sitemap,
{'sitemaps': {'blog': GenericSitemap(info_dict, priority=0.6)}},
name='django.contrib.sitemaps.views.sitemap'),
]
静态视图的站点地图
通常,您希望搜索引擎抓取工具编制既不是对象详细信息页也不是平板页的视图。 解决方案是显式列出项目中这些视图的URL名称,并在站点地图的位置方法中调用reverse()。 例如:
# sitemaps.py
from django.contrib import sitemaps
from django.core.urlresolvers 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.conf.urls import url
from django.contrib.sitemaps.views import sitemap
from .sitemaps import StaticViewSitemap
from . import views
sitemaps = {
'static': StaticViewSitemap,
}
urlpatterns = [
url(r'^$', views.main, name='main'),
url(r'^about/$', views.about, name='about'),
url(r'^license/$', views.license, name='license'),
# ...
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap')
]
创建一个站点地图索引
站点地图框架还能够创建一个引用个别站点地图文件的站点地图索引,每个站点地图词典中定义一个节点。 使用的唯一区别是:
- 您在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 = [
url(r'^sitemap\.xml$', views.index, {'sitemaps': sitemaps}),
url(r'^sitemap-(?P<section>.+)\.xml$', views.sitemap,
{'sitemaps': sitemaps}),
]
这将自动生成一个引用sitemap-flatpages.xml和sitemap-blog.xml的sitemap.xml文件。 Sitemap类和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 = [
url(r'^sitemap\.xml$',
cache_page(86400)(sitemaps_views.index),
{'sitemaps': sitemaps, 'sitemap_url_name': 'sitemaps'}),
url(r'^sitemap-(?P<section>.+)\.xml$',
cache_page(86400)(sitemaps_views.sitemap),
{'sitemaps': sitemaps}, name='sitemaps'),
]
模板定制
如果您希望为网站上的每个站点地图或站点地图索引使用不同的模板,则可以通过将URL参数传递给站点地图和索引视图来指定它:
from django.contrib.sitemaps import views
urlpatterns = [
url(r'^custom-sitemap\.xml$', views.index, {
'sitemaps': sitemaps,
'template_name': 'custom_sitemap.html'
}),
url(r'^custom-sitemap-(?P<section>.+)\.xml$', views.sitemap, {
'sitemaps': sitemaps,
'template_name': 'custom_sitemap.html'
}),
]
上下文变量
在为index()和sitemap()视图定制模板时,可以依赖以下上下文变量。
下标
变量站点地图是每个站点地图的绝对URL列表。
网站地图
变量urlset
是应该出现在站点地图中的URL列表。 每个网址都显示Sitemap类中定义的属性:
- changefreq
- item
- lastmod
- location
- priority
为每个网址添加了项目属性,以便更灵活地定制模板,例如Google新闻站点地图。 假设Sitemap的items()会返回带有publication_data和tags字段的项目列表,则会生成一个Google兼容的站点地图:
{% spaceless %}
{% for url in urlset %}
{{ url.location }}
{% if url.lastmod %}{{ url.lastmod|date:"Y-m-d" }}{% endif %}
{% if url.changefreq %}{{ url.changefreq }}{% endif %}
{% if url.priority %}{{ url.priority }}{% endif %}
{% if url.item.publication_date %}{{ url.item.publication_date|date:"Y-m-d" }}{\
% endif %}
{% if url.item.tags %}{{ url.item.tags }}{% endif %}
{% endfor %}
{% endspaceless %}
Ping Google
您可能希望在网站地图发生变化时ping Google,让其知道重新为您的网站建立索引。 sitemaps框架提供了一个功能来做到这一点:
django.contrib.syndication.ping_google()
ping_google()采用一个可选参数sitemap_url,它应该是站点站点地图的绝对路径(例如'/sitemap.xml')。 如果没有提供此参数,ping_google()会尝试通过在URLconf中执行反向查找来找出您的站点地图。 如果ping_google()无法确定您的站点地图URL,则会引发异常django.contrib.sitemaps.SitemapNotFound。
调用ping_google()的一种有用方法来自模型的save()方法:
from django.contrib.sitemaps import ping_google
class Entry(models.Model):
# ...
def save(self, force_insert=False, force_update=False):
super(Entry, self).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()时可能不希望引入该网络开销。
通过manage.py Ping Google
一旦sitemaps应用程序被添加到您的项目中,您也可以使用ping_google管理命令ping Google:
python manage.py ping_google [/sitemap.xml]
首先向Google注册!只有在您使用Google网站管理员工具注册您的网站时,ping_google()命令才有效。
下一步是什么?
接下来,我们将继续深入研究Django为Django会话框架提供的内置工具。
网友评论