-
python全栈开发中Django的输出非HTML内容(2)
sitemap视图需要一个额外的必须的参数: {'sitemaps': sitemaps} 。 sitemaps 应该是一个字典,它把一个短的块标签(例如,blog 或 news )映射到它的 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/'
§ 差的: 'http://example.com/foo/bar/'
如果没有提供 location , 框架将会在每个 items() 返回的对象上调用 getabsoluteurl() 方法.
lastmod (可选): 对象的最后修改日期, 作为一个Python datetime 对象.
changefreq (可选):对象变更的频率。可选的值如下(详见Sitemaps文档):
§ 'always'
§ 'hourly'
§ 'daily'
§ 'weekly'
§ 'monthly'
§ 'yearly'
§ 'never'
priority (可选):取值范围在 0.0 and 1.0 之间,用来表明优先级。默认值为 0.5 ;请详见http://sitemaps.org 文档。
快捷方式
sitemap框架提供了一些常用的类。在下一部分中会看到。
FlatPageSitemap
django.contrib.sitemaps.FlatPageSitemap 类涉及到站点中所有的flat page,并在sitemap中建立一个入口。但仅仅只包含location 属性,不支持 lastmod , changefreq ,或者 priority 。
参见第16章获取有关flat page的更多的内容.
GenericSitemap
GenericSitemap 与所有的通用视图一同工作(详见第9章)。
你可以如下使用它,创建一个实例,并通过 infodict 传递给通用视图。唯一的要求是字典包含 queryset 这一项。也可以用datefield 来指明从 queryset 中取回的对象的日期域。这会被用作站点地图中的 lastmod 属性。你也可以向 GenericSitemap 的构造函数传递 priority 和 changefreq 来指定所有URL的相应属性。
下面是一个使用 FlatPageSitemap and 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.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() 。
备注
在本书写成的时候, 只有Google可以响应sitemap更新通知。然而,Yahoo和MSN可能很快也会支持这些通知。
到那个时候,把“pinggoogle()”这个名字改成“pingsearch_engines()”会比较好。所以还是到http://www.djangoproject.com/documentation/0.96/sitemaps/ 去检查一下最新的站点地图文档。
pinggoogle() 有一个可选的参数 sitemapurl ,它应该是你的站点地图的URL绝对地址(例如: /sitemap.xml )。如果不提供该参数, ping_google() 将尝试通过反查你的URLconf来找到你的站点地图。
如果不能够确定你的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):
super(Entry, self).save()
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给你的很好的内置工具。 在第12章,您将看到提供用户自定义站点所需要的所有工具: sessions, users 和authentication.
继续前行!