Sitemap 框架
sitemap 是你服务器上的一个XML文件,它告诉搜索引擎你的页面的更新频率和某些页面相对于其它页面的重要性。 这个信息会帮助搜索引擎索引你的网站。
例如,这是 Django 网站(http://www.djangoproject.com/sitemap.xml)sitemap的一部分:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.djangoproject.com/documentation/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>http://www.djangoproject.com/documentation/0_90/</loc>
<changefreq>never</changefreq>
<priority>0.1</priority>
</url>
...
</urlset>
需要了解更多有关 sitemaps 的信息,请参见http://www.sitemaps.org/。
Django sitemap 框架允许你用 Python 代码来表述这些信息,从而自动创建这个XML文件。要创建一个站点地图,你只需要写一个Sitemap
类,并且在URLconf中指向它。
安装
要安装 sitemap 应用程序,按下面的步骤进行:
- 将
'django.contrib.sitemaps'
添加到您的INSTALLED_APPS
设置中。 - 确保
'django.template.loaders.app_directories.load_template_source'
在您的TEMPLATE_LOADERS
设置中。 默认情况下它在那里, 所以,如果你已经改变了那个设置的话,只需要改回来即可。 - 确定您已经安装了 sites 框架 (参见第14章)。
注意
sitemap 应用程序没有安装任何数据库表. 它需要加入到 INSTALLED_APPS
中的唯一原因是:这样 load_template_source
模板加载器可以找到默认的模板。
初始化
要在您的Django站点中激活sitemap生成, 请在您的 URLconf 中添加这一行:
(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
这行告诉Django,当一个客户端访问/sitemap.xml
的时候创建一个sitemap。注意!在sitemap.xml
中.
符号会转义成/
,因为.
符号在正则表达式中有特殊含义。
sitemap文件的名字无关紧要,但是它在服务器上的位置却很重要。 搜索引擎只索引你的sitemap中当前URL级别及其以下级别的链接。 用一个实例来说,如果 sitemap.xml
位于你的根目录,那么它将引用任何的URL。 然而,如果你的sitemap位于 /content/sitemap.xml
,那么它只引用以 /content/
打头的URL。
sitemap视图需要一个额外的必须的参数: {'sitemaps': sitemaps}
。 sitemaps应该是一个字典,这个字典将label(例如blog或者new)映射到它的Sitemap类上(例如BlogSitemap
或者NewsSitemap
) 。它也可以映射到Sitemap类的实例上(比如BlogSitemap(some_var)
) 。
Sitemap 类
Sitemap
类展示了一个进入地图站点简单的Python类片断。例如,一个 Sitemap
类能展现所有日志入口,而另外一个能够调度所有的日历事件。
在最简单的例子中,所有部分可以全部包含在一个 sitemap.xml
中,也可以使用框架来产生一个站点地图,为每一个独立的部分产生一个单独的站点文件。
Sitemap
类必须是 django.contrib.sitemaps.Sitemap
的子类。他们可以存在于您的代码树的任何地方。
例如假设你有一个blog系统,有一个 Entry
的model,并且你希望你的站点地图包含所有连到你的blog入口的超链接。你的 Sitemap
类很可能是这样的:
from django.contrib.sitemaps import Sitemap
from mysite.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
声明一个 Sitemap
和声明一个 Feed
看起来很类似;这都是预先设计好的。
如同 Feed
类一样, Sitemap
成员也既可以是方法,也可以是属性。想要知道更详细的内容,请参见上文 《一个复杂的例子》章节。
一个 Sitemap
类可以定义如下方法/属性:
items
(必需 ):提供对象列表。 框架并不关心对象的 类型 ;唯一关心的是这些对象会传递给 location() , lastmod() , changefreq() ,和 priority() 方法。location
(可选): 给定对象的绝对URL。 绝对URL不包含协议名称和域名。 下面是一些例子:- 好的:
'/foo/bar/'
- 差的:
'example.com/foo/bar/'
- Bad: 'http://example.com/foo/bar/'
- 好的:
如果没有提供 location
, 框架将会在每个 items()
返回的对象上调用 get_absolute_url()
方法.
- lastmod (可选): 对象的最后修改日期, 作为一个
Python datetime
对象。 - changefreq (可选):对象变更的频率。 可选的值如下(详见Sitemaps文档):
- 'always'
- 'hourly'
- 'daily'
- 'weekly'
- 'monthly'
- 'yearly'
- 'never'
- priority (可选):取值范围在
0.0
和1.0
之间,用来表明优先级。
快捷方式
sitemap框架提供了一些常用的类。 在下一部分中会看到。
1、FlatPageSitemap
django.contrib.sitemaps.FlatPageSitemap
类涉及到站点中所有的flat page,并在sitemap中建立一个入口。 但仅仅只包含 location 属性,不支持 lastmod
, changefreq
,或者 priority
。
参见第16章获取有关flat page的更多的内容。
2、GenericSitemap
GenericSitemap
与所有的通用视图一同工作(详见第9章)。
你可以如下使用它,创建一个实例,并通过 info_dict
传递给通用视图。 唯一的要求是字典包含 queryset
这一项。 也可以用 date_field
来指明从 queryset
中取回的对象的日期域。 这会被用作站点地图中的 lastmod
属性。
下面是一个使用 FlatPageSitemap
和 GenericSiteMap
(包括前面所假定的 Entry
对象)的URLconf:
from django.conf.urls.defaults import *
from django.contrib.sitemaps import FlatPageSitemap, GenericSitemap
from mysite.blog.models import Entry
info_dict = {
'queryset': Entry.objects.all(),
'date_field': 'pub_date',
}
sitemaps = {
'flatpages': FlatPageSitemap,
'blog': GenericSitemap(info_dict, priority=0.6),
}
urlpatterns = patterns('',
# some generic view using info_dict
# ...
# the sitemap
(r'^sitemap\.xml$',
'django.contrib.sitemaps.views.sitemap',
{'sitemaps': sitemaps})
)
创建一个Sitemap索引
sitemap框架同样可以根据 sitemaps 字典中定义的单独的sitemap文件来建立索引。用法区别如下:
您在您的URLconf 中使用了两个视图:
django.contrib.sitemaps.views.index
和django.contrib.sitemaps.views.sitemap
.django.contrib.sitemaps.views.index
和django.contrib.sitemaps.views.sitemap
django.contrib.sitemaps.views.sitemap
视图需要带一个section
关键字参数。
这里是前面的例子的相关的 URLconf 行看起来的样子:
(r'^sitemap.xml$',
'django.contrib.sitemaps.views.index',
{'sitemaps': sitemaps}),
(r'^sitemap-(?P<section>.+).xml$',
'django.contrib.sitemaps.views.sitemap',
{'sitemaps': sitemaps})
这将自动生成一个 sitemap.xml
文件,它同时引用 sitemap-flatpages.xml
和 sitemap-blog.xml
。 Sitemap
类和 sitemaps
目录根本没有更改。
通知Google
当你的sitemap变化的时候,你会想通知Google,以便让它知道对你的站点进行重新索引。框架就提供了这样的一个函数: django.contrib.sitemaps.ping_google()
。
ping_google()
有一个可选的参数 sitemap_url
,它应该是你的站点地图的URL绝对地址(例如:
如果不能够确定你的sitemap URL, ping_google()
会引发 django.contrib.sitemaps.SitemapNotFound
异常。
我们可以通过模型中的 save()
方法来调用 ping_google()
:
from django.contrib.sitemaps import ping_google
class Entry(models.Model):
# ...
def save(self, *args, **kwargs):
super(Entry, self).save(*args, **kwargs)
try:
ping_google()
except Exception:
# Bare 'except' because we could get a variety
# of HTTP-related exceptions.
pass
一个更有效的解决方案是用 cron
脚本或任务调度表来调用 ping_google()
,该方法使用Http直接请求Google服务器,从而减少每次调用 save()
时占用的网络带宽。
最后,如果'django.contrib.sitemaps'
已经在你的INSTALLED_APPS
里面,那么你的manage.py
就有了一个新的命令,ping_google
,这是一个非常有用的命令行工具,用法如下:
python manage.py ping_google /sitemap.xml