在Django中使用Sitemap的方法讲解
sitemap是你服务器上的一个XML文件,它告诉搜索引擎你的页面的更新频率和某些页面相对于其它页面的重要性。这个信息会帮助搜索引擎索引你的网站。
例如,这是Django网站(http://www.djangoproject.com/sitemap.xml)sitemap的一部分:
<?xmlversion="1.0"encoding="UTF-8"?> <urlsetxmlns="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/.
Djangositemap框架允许你用Python代码来表述这些信息,从而自动创建这个XML文件。要创建一个站点地图,你只需要写一个``Sitemap``类,并且在URLconf中指向它。
安装
要安装sitemap应用程序,按下面的步骤进行:
- 将'django.contrib.sitemaps'添加到您的INSTALLED_APPS设置中.
- 确保'django.template.loaders.app_directories.load_template_source'在您的TEMPLATE_LOADERS设置中。默认情况下它在那里,所以,如果你已经改变了那个设置的话,只需要改回来即可。
- 确定您已经安装了sites框架.
Note
sitemap应用程序没有安装任何数据库表.它需要加入到INSTALLED_APPS中的唯一原因是:这样load_template_source模板加载器可以找到默认的模板.TheonlyreasonitneedstogointoINSTALLED_APPSissotheload_template_sourcetemplateloadercanfindthedefaulttemplates.
Initialization
要在您的Django站点中激活sitemap生成,请在您的URLconf中添加这一行:
(r'^sitemap\.xml$','django.contrib.sitemaps.views.sitemap',{'sitemaps':sitemaps})
ThislinetellsDjangotobuildasitemapwhenaclientaccesses/sitemap.xml.Notethatthedotcharacterinsitemap.xmlisescapedwithabackslash,becausedotshaveaspecialmeaninginregularexpressions.
sitemap文件的名字无关紧要,但是它在服务器上的位置却很重要。搜索引擎只索引你的sitemap中当前URL级别及其以下级别的链接。用一个实例来说,如果sitemap.xml位于你的根目录,那么它将引用任何的URL。然而,如果你的sitemap位于/content/sitemap.xml,那么它只引用以/content/打头的URL。
sitemap视图需要一个额外的必须的参数:{'sitemaps':sitemaps}.sitemapsshouldbeadictionarythatmapsashortsectionlabel(e.g.,blogornews)toitsSitemapclass(e.g.,BlogSitemaporNewsSitemap).ItmayalsomaptoaninstanceofaSitemapclass(e.g.,BlogSitemap(some_var)).
Sitemap类
Sitemap类展示了一个进入地图站点简单的Python类片断.例如,一个Sitemap类能展现所有日志入口,而另外一个能够调度所有的日历事件。Forexample,oneSitemapclasscouldrepresentalltheentriesofyourweblog,whileanothercouldrepresentalloftheeventsinyoureventscalendar.
在最简单的例子中,所有部分可以全部包含在一个sitemap.xml中,也可以使用框架来产生一个站点地图,为每一个独立的部分产生一个单独的站点文件。
Sitemap类必须是django.contrib.sitemaps.Sitemap的子类.他们可以存在于您的代码树的任何地方。
例如假设你有一个blog系统,有一个Entry的model,并且你希望你的站点地图包含所有连到你的blog入口的超链接。你的Sitemap类很可能是这样的:
fromdjango.contrib.sitemapsimportSitemap frommysite.blog.modelsimportEntry classBlogSitemap(Sitemap): changefreq="never" priority=0.5 defitems(self): returnEntry.objects.filter(is_draft=False) deflastmod(self,obj): returnobj.pub_date
声明一个Sitemap和声明一个Feed看起来很类似;这都是预先设计好的。
如同Feed类一样,Sitemap成员也既可以是方法,也可以是属性。
一个Sitemap类可以定义如下方法/属性:
items(必需):提供对象列表。框架并不关心对象的类型;唯一关心的是这些对象会传递给location(),lastmod(),changefreq(),和priority()方法。
location(可选):给定对象的绝对URL。绝对URL不包含协议名称和域名。下面是一些例子:
- 好的:'/foo/bar/''/foo/bar/'
- 差的:'example.com/foo/bar/''example.com/foo/bar/'
如果没有提供location,框架将会在每个items()返回的对象上调用get_absolute_url()方法.
lastmod(可选):对象的最后修改日期,作为一个Pythondatetime对象.Theobject'slastmodificationdate,asaPythondatetimeobject.
changefreq(可选):对象变更的频率。可选的值如下(详见Sitemaps文档):
- 'always'
- 'hourly'
- 'daily'
- 'weekly'
- 'monthly'
- 'yearly'
- 'never'
- priority(可选):取值范围在0.0and1.0之间,用来表明优先级。
快捷方式
sitemap框架提供了一些常用的类。在下一部分中会看到。
FlatPageSitemap
django.contrib.sitemaps.FlatPageSitemap类涉及到站点中所有的flatpage,并在sitemap中建立一个入口。但仅仅只包含location属性,不支持lastmod,changefreq,或者priority。
GenericSitemap
GenericSitemap与所有的通用视图一同工作(详见第9章)。
你可以如下使用它,创建一个实例,并通过info_dict传递给通用视图。唯一的要求是字典包含queryset这一项。也可以用date_field来指明从queryset中取回的对象的日期域。这会被用作站点地图中的lastmod属性。
下面是一个使用FlatPageSitemapandGenericSiteMap(包括前面所假定的Entry对象)的URLconf:
fromdjango.conf.urls.defaultsimport* fromdjango.contrib.sitemapsimportFlatPageSitemap,GenericSitemap frommysite.blog.modelsimportEntry info_dict={ 'queryset':Entry.objects.all(), 'date_field':'pub_date', } sitemaps={ 'flatpages':FlatPageSitemap, 'blog':GenericSitemap(info_dict,priority=0.6), } urlpatterns=patterns('', #somegenericviewusinginfo_dict #... #thesitemap (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绝对地址(例如:
如果不能够确定你的sitemapURL,ping_google()会引发django.contrib.sitemaps.SitemapNotFound异常。
我们可以通过模型中的save()方法来调用ping_google():
fromdjango.contrib.sitemapsimportping_google classEntry(models.Model): #... defsave(self,*args,**kwargs): super(Entry,self).save(*args,**kwargs) try: ping_google() exceptException: #Bare'except'becausewecouldgetavariety #ofHTTP-relatedexceptions. pass
一个更有效的解决方案是用cron脚本或任务调度表来调用ping_google(),该方法使用Http直接请求Google服务器,从而减少每次调用save()时占用的网络带宽。ThefunctionmakesanHTTPrequesttoGoogle'sservers,soyoumaynotwanttointroducethatnetworkoverheadeachtimeyoucallsave().
Finally,if'django.contrib.sitemaps'isinyourINSTALLED_APPS,thenyourmanage.pywillincludeanewcommand,ping_google.Thisisusefulforcommand-lineaccesstopinging.Forexample:
pythonmanage.pyping_google/sitemap.xml