通常當我們談到開發網站時,我們都是指生成一些HTML
當然也有很多HTML之外的東西,我們使用web來發布所有的內容,不僅僅是HTML
到目前為止我們都是在關注通常的HTML生成,但是本章將繞道來看看使用Django生成其它類型的內容
你可以使用Django方便的內建工具來生成一些常見的非HTML內容:
RSS/Atom聚合
Sitemaps,可以被Google,Yahoo和微軟的搜索引擎搜索
JSON和XML序列化的模型(通常為AJAX方法使用)
我們將談到上面的每一個工具,但是首先來看看一些基礎
基礎
還記得第3章的內容嗎?
視圖方法或者簡短來說視圖是簡單的Python方法,它得到Web請求并返回Web應答,這個應答可以是Web頁面的HTML內容,
或者是一個重定向,或者是404錯誤,或者是一個XML文檔,或者是一個image,...,或者是其它的任何東西
更正式的,Django視圖方法必須接受一個HttpRequest實例作為它的第一個參數并且返回一個HttpResponse實例
從視圖返回非HTML內容的關鍵在于HttpResponse類,特別是mimetype構造函數的參數,通過改變mimetype我們可以指示
瀏覽器我們返回的不同類型的對象
下面是一個簡單的例子,我們來看看一個返回PNG圖像的視圖,為了讓事情保持簡單,我們只是從硬盤讀一個文件:
- from django.http import HttpResponse
- def my_image(request):
- image_data = open("/path/to/my/image.png", "rb").read()
- return HttpResponse(image_data, mimetype="image/png")
僅此而已!如果你改變open()調用的圖像路徑為一個真正圖像的路徑,你可以使用這個非常簡單的視圖來處理圖像,瀏覽
器將正確的顯示它
另外一個需要記住的重要事情是HttpResponse對象實現了Python的標準文件API,這意味著你可以傳遞一個HttpResponse
實例給Python(或者第三方庫)需要文件的任何地方
例如我們看看用Django生成CSV
生成CSV
CSV是通常被電子制表軟件使用的簡單數據形式,它基本上是表的一系列行,行的每個單元用逗號分隔(CSV表示"逗號分隔
的值"),例如,下面是FAA收集的最近10年的"不規矩"的航空旅客的列表:
- Year,Unruly Airline Passengers
- 1995,146
- 1996,184
- 1997,235
- 1998,200
- 1999,226
- 2000,251
- 2001,299
- 2002,273
- 2003,281
- 2004,304
- 2005,203
注意參看http://www.faa.gov/data_statistics/passengers_cargo/unruly_passengers/得到此數據
不幸的是,CSV不是正式定義的格式,軟件的不同部分生成和使用不同的CSV,這讓它有點難以使用
幸運的是,Python有一個標準CSV庫csv,它是非常防彈的
和Django使用這個庫的關鍵是csv模塊的CSV創建能力表現為類似文件對象,Django的HttpResponse對象也類似文件對象:
- import csv
- from django.http import HttpResponse
- # Number of unruly passengers each year 1995 - 2005
- UNRULY_PASSENGERS = [146,184,235,200,226,251,299,273,281,304,203]
- def unruly_passengers_csv(request):
- # Create the HttpResponse object with the appropriate CSV header.
- response = HttpResponse(mimetype='text/csv')
- response['Content-Disposition'] = 'attachment; filename=unruly.csv'
- # Create the CSV writer using the HttpResponse as the "file"
- writer = csv.writer(response)
- writer.writerow(['Year', 'Unruly Airline Passengers'])
- for (year, num) in zip(range(1995, 2006), UNRULY_PASSENGERS):
- writer.writerow([year, num])
- return response
代碼和注釋看起來非常清楚,但是有一些事情需要注意:
1,應答的mime-type為為text/csv,這告訴瀏覽器文檔是一個CSV文件,而不是HTML文件
2,應答有一個另外的Content-Disposition頭部,它包含CSV文件的名字,這個頭部("attachment")將告訴瀏覽器提示
一個位置來保存文件(而不是顯示它),這個文件名隨意,你想叫它什么都可以,它將被瀏覽器的"Save as..."對話框使用
3,CSV生成API很簡單,只是傳遞response作為第一個參數給csv.writer,csv.writer方法期望一個類似文件的對象,
然后HttpResponse對象來付帳
4,對你的CSV文件的每一行調用writer.writerow,傳遞一個iterable對象給它,例如列表或者元組
5,CSV模塊幫你關注引號,所以你不需要擔心escape含有引號或逗號的字符串,只需傳遞信息給writerow(),它將給你
做正確的事情
你通常將重復這個模式,創建一個HttpResponse應答對象(用一個特殊的mime-type),把它傳遞給一個期望文件的東西,
然后返回應答,任何你生成非HTML內容的時候都可以這樣做
讓我們看看一些更多的例子
生成PDF
PDF(Portable Document Format)是Adobe開發的格式,它用來展示可打印的文檔,并具有象素完美的格式,內嵌的字體和
2D向量圖形,你可以把PDF文檔當作可打印文檔的數字等價物,確實,PDF通常用在當你需要把一份文檔給另一個人打印時
有了絕佳的ReportLab開源庫(http://www.reportlab.org/rl_toolkit.html)你可以使用Python和Django輕松
生成PDF,動態生成PDF文件的好處是你可以創建自定義的PDF來滿足不同的目的,如為不同的用戶或不同的內容等
例如,我們在KUSports.com使用Django和ReportLab來為參加March Madness(大學籃球賽)的人們生成自定義的可打印的
NCAA錦標賽brackets
安裝ReportLab
但是,在你生成任何PDF之前你需要安裝ReportLab,這通常很簡單
只需從http://www.reportlab.org/downloads.html下載和安裝庫
用戶手冊(不巧也是PDF文件)在http://www.reportlab.org/rsrc/userguide.pdf并有額外的安裝幫助
注意,如果你使用時髦的Linux發布,你可能想在手動安裝ReportLab前檢查你的包管理工具,大部分包資源庫已經
包含了ReportLab,例如,如果你使用(絕佳的)Ubuntu發布,一個簡單的aptitude install python-reportlab將很好的
安裝它
通過在Python交互解釋器里import它來測試你的安裝:
- >>> import reportlab
如果上面的命令不觸發任何錯誤,表明安裝的組件已經工作
寫視圖
再說一遍,使用Django動態生成PDF的關鍵是ReportLab API基于類似文件的對象,而且Django的HttpResponse對象也是
類似文件的對象,這里是一個"Hello World"例子:
- from reportlab.pdfgen import canvas
- from django.http import HttpResponse
- def hello_pdf(request):
- # Create the HttpResponse object with the appropriate PDF headers.
- response = HttpResponse(mimetype='application/pdf')
- response['Content-Disposition'] = 'attachment; filename=hello.pdf'
- # Create the PDF object, using the response object as its "file."
- p = canvas.Canvas(response)
- # Draw things on the PDF. Here's where the PDF generation happens.
- # See the ReportLab documentation for the full list of functionality.
- p.drawString(100, 100, "Hello world.")
- # Close the PDF object cleanly, and we're done.
- p.showPage()
- p.save()
- return response
和上面一樣,有一些地方需要按順序注意一下:
1,這里我們使用application/pdf mime-type,這告訴瀏覽器文檔是一個PDF文件,而不是一個HTML文件,如果你不寫
這個,瀏覽器將可能把輸出解釋為HTML,這將導致在瀏覽器觸發錯誤
2,ReportLab API很簡單,只需把response作為第一個參數傳遞給canva.Canvas,Canvas類期望一個類似文件的對象,
然后HttpResponse對象來付帳
3,所有后面的PDF生成方法在PDF對象(這里是p)上調用,而不是在response上
4,最后,在PDF文件上調用showPage()和save()很重要(否則你將得到一個糟糕的PDF文件)
復雜的PDF
如果你使用ReportLab創建一個復雜的PDF文檔,考慮為你的PDF文件使用cStringIO庫作為一個臨時存儲位置,cStringIO
庫提供一個非常有效的類似文件的對象接口(比天真的HttpResponse作為文件的實現更好)
這里是使用cStringIO來重寫上面的"Hello World"例子:
- from cStringIO import StringIO
- from reportlab.pdfgen import canvas
- from django.http import HttpResponse
- def hello_pdf(request):
- # Create the HttpResponse object with the appropriate PDF headers.
- response = HttpResponse(mimetype='application/pdf')
- response['Content-Disposition'] = 'attachment; filename=hello.pdf'
- buffer = StringIO()
- # Create the PDF object, using the StringIO object as its "file."
- p = canvas.Canvas(buffer)
- # Draw things on the PDF. Here's where the PDF generation happens.
- # See the ReportLab documentation for the full list of functionality.
- p.drawString(100, 100, "Hello world.")
- # Close the PDF object cleanly.
- p.showPage()
- p.save()
- # Get the value of the StringIO buffer and write it to the response.
- response.write(buffer.getvalue())
- return response
其它可能性
用Python你可以生成整個世界的其它類型的內容,這里是一些更多的主意,其中一些是你可以用來實現它們的庫:
生成ZIP文件:Python的zipfile模塊的標準庫,它可以讀寫壓縮的ZIP文件,你可以使用它來提供任意文件的存檔,
或者有需求時把大文檔壓縮,你同樣可以使用標準庫的tarfile模塊來生成TAR文件
動態圖像生成:Python圖像庫(http://www.pythonware.com/products/pil/)是一個非常奇妙的用來生成圖像
(PNG,JPEG,GIF等等)的工具庫,你可以用它來自動縮小圖像,把多幅圖像組合成單獨畫面,甚至做基于web的圖像處理
分圖和制圖:有許多不可思議的強大的Python分圖和制圖庫,你可以用它們生成任意的maps,charts,plots和graphs
我們不能列出所有的,所以這里是一些不錯的:
matplotlib(http://matplotlib.sourceforge.net/),它可以用來生成通常用MatLab或者Mathematica來生成
的高質量的plots
pygraphviz(https://networkx.lanl.gov/wiki/pygraphviz)
這是一個Graphviz圖形布局工具庫(http://graphviz.org/)的接口,用來生成圖形或網絡的結構化diagrams
通常來說,任何可以寫文件的Python庫都可以在Django中使用,可能性真的是無限的
既然我們看到了生成非HTML內容的基礎,讓我們進一步抽象,Django帶有一些非常俏皮的內建工具用來生成一些通常類型
的非HTML內容
聚合框架
Django帶有一個高級的聚合生成框架,它讓創建RSS和Atom feeds非常容易
什么是RSS?什么是Atom?
RSS和Atom都是基于XML的格式,你可以用來提供自動更新你的站點內容的"feeds"
閱讀更多關于RSS的內容http://www.whatisrss.com
以及更多關于Atome的內容http://www.atomenabled.org
創建任何聚合只需寫一個很短的Python類,你可以想創建多少feeds就創建多少
Django也帶一個低級feed生成API,如果你想在Web context之外生成feeds或者用一些更低級的方式的話可以使用它
高級框架概覽
高級feed生成框架是一個默認綁定到/feeds/的視圖,Django使用URL的其它部分(在/feeds/之后的任何東西)來決定輸出
哪個feed
為了創建一個feed,只需寫一個Feed類并在你的URL配置里指出(參考第3章和第8章得到更多關于URL配置)
初始化
為了在你的Django站點里激活聚合,你需要把下面的內容添加到你的URL配置:
- (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}),
這會告訴Django使用RSS框架來處理所有的以"feeds/"開頭的URL(你可以改變"feeds/"前綴來滿足你自己的需求)
這個URL配置有另外一個參數{'feed_dict': feeds},使用這個額外參數來把改URL下發布的feeds傳遞給聚合框架
特別的,feed_dict應該是一個映射feed的slug(簡短URL標簽)到它的Feed類的字典
你可以在URL配置本身里定義feed_dict,這里是一個完整的例子:
- from django.conf.urls.defaults import *
- from myproject.feeds import LatestEntries, LatestEntriesByCategory
- feeds = {
- 'latest': LatestEntries,
- 'categories': LatestEntriesByCategory,
- }
- urlpatterns = patterns('',
- # ...
- (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed',
- {'feed_dict': feeds}),
- # ...
- )
上面的例子注冊了兩個feeds:
通過LatestEntries展示的feed對應feeds/latest/
通過LatestEntriesByCategory展示的feed對應feeds/categories/
一旦建立好之后,你只需定義Feed類本身
Feed類
一個Feed類是展示聚合feed的簡單的Python類,一個Feed可以很簡單(例如一個"站點新聞"feed或者顯示博客最近條目的
基本feed)也可以更復雜(例如顯示博客特殊類別的所有條目,該類別可變)
Feed類必須繼承django.contrib.syndication.feeds.Feed,它們可以在你的代碼樹的任何位置
簡單的例子
這個簡單的例子來自于chicagocrime.org,描述最近5項新聞條目的feed:
- from django.contrib.syndication.feeds import Feed
- from chicagocrime.models import NewsItem
- class LatestEntries(Feed):
- title = "Chicagocrime.org site news"
- link = "/sitenews/"
- description = "Updates on changes and additions to chicagocrime.org."
- def items(self):
- return NewsItem.objects.order_by('-pub_date')[:5]
這里需要注意的重要事情:
1,這個類繼承django.contrib.syndication.feeds.Feed
2,title,link和description對應標準的RSS(title),(link)和(description)元素
3,items()是簡單的返回在feed中作為(item)元素的對象列表的方法,盡管這個例子使用Django的數據庫API返回
NewsItem對象,items()不一定必須返回模型實例
你可以通過使用Django模型得到一些功能,但是items()可以返回任何你想要類型的對象
只有另一個更多的步驟,在一個RSS feed里,每個(item)有一個(title),(link)和(description),我們需要告訴框架
把哪些數據放到那些元素中
4,為了指定(title)和(description)的內容,創建叫feeds/latest_title.html和feeds/latest_description.html的
Django模板(參考第4章),latest是給定feed的URL配置里指定的slug
注意.html擴展名是必需的
RSS系統為每個條目渲染該模板,并傳遞兩個模板context變量:
obj
當前對象(在items()里返回的對象里的一個)
site
一個顯示當前站點的django.models.core.sites.Site對象,它對{{ site.domain }}或者{{ site.name }}有用
如果你不為title或description創建模板,框架將默認使用模板"{{ obj }}",對象的普通的字符串展示
你也可以通過指定title_template和description_template作為你的Feed類的屬性來改變這兩個模板的名字
5,為了指定(link)的內容,你有兩個選擇,對items()的每個條目,Django首先嘗試執行對象的get_absolute_url()方法
如果該方法不存在,則嘗試調用Feed類的item_link()方法,并把該對象本身作為參數item傳遞過去
6,對于上面的LatestEntries例子,我們可以有一些簡單的feed模板,latest_title.html包含:
- {{ obj.title }}
latest_description.html包含:
- {{ obj.description }}
這簡直太簡單了...
復雜的例子
框架也通過參數提供更復雜的feeds
例如,chicagocrime.org提供一個最近在Chicago每個警察打擊的犯罪的RSS feed,為每個警察打擊的犯罪創建單獨的
Feed類是很愚蠢的,這將違反DRY(Don't Repeat Yourself)原則并把數據和編程邏輯耦合
聚合框架讓你構建基于feed的URL信息輸出items的通用feeds
在chicagocrime.org,警察打擊feeds可以像這樣通過URL訪問:
/rss/beats/0613/,返回0613打擊的最近犯罪
/rss/beats/1424/,返回1424打擊的最近犯罪
這里的slug是"beats",聚合框架查看slug后面另外的URL,0613和1424,并可以告訴它那些URL表示什么,以及它們怎樣
影響feed中哪些條目被發表
一個例子將把事情解釋清楚,這里是那些打擊專有的feeds的代碼:
- from django.core.exceptions import ObjectDoesNotExist
- class BeatFeed(Feed):
- def get_object(self, bits):
- # In case of "/rss/beats/0613/foo/bar/baz/", or other such
- # clutter, check that bits has only one member.
- if len(bits) != 1:
- raise ObjectDoesNotExist
- return Beat.objects.get(beat__exact=bits[0])
- def title(self, obj):
- return "Chicagocrime.org: Crimes for beat %s" % obj.beat
- def link(self, obj):
- return obj.get_absolute_url()
- def description(self, obj):
- return "Crimes recently reported in police beat %s" % obj.beat
- def items(self, obj):
- crimes = Crime.objects.filter(beat__id__exact=obj.id)
- return crimes.order_by('-crime_date')[:30]
這里是RSS框架遵循的基本算法,給定這個類和一個請求到/rss/beats/0613/:
1,框架得到/rss/beats/0613/的URL并注意到在slug后面有一個額外的URL片段,則它通過斜線字符("/")把后面的字符串
分隔開然后調用Feed類的get_object()方法并把片段傳遞過去
這里的片段是['0613'],對于/rss/beats/0613/foo/bar/的請求,片段則為['0613', 'foo', 'bar']
2,get_object()負責返回從給定片段得到給定的打擊
在這里,它使用Django數據庫API來查詢打擊,注意如果給定非法參數的話get_object()應該觸發
django.core.exceptions.ObjectDoesNotExist異常,Beat.objects.get()調用沒有try/except包圍,因為沒必要,
這個方法在失敗時觸發Beat.DoesNotExist,而Beat.DoesNotExist是ObjectDoesNotExist的子類,在get_object()里觸發
ObjectDoesNotExist異常告訴Django對該請求產生404錯誤
3,為了生成feed的(title),(link)和(description),Django使用title(),link()和description()方法,在上個例子
中,它們是簡單的字符串類屬性,但是這個例子說明它們可以是字符串或者方法,對title,link和description中的任
一個,Django遵循這個算法:
首先,它嘗試調用一個方法,傳遞obj參數,這里obj是get_object()返回的對象
失敗的話,它嘗試調用一個沒有參數的方法
再失敗的話,它使用類屬性
4,最后,注意這個例子中的items()也需要obj參數,items的算法和上一步描述的一樣,它嘗試items(obj),然后是
items(),最后是一個items類屬性(它應該是一個列表)
Feed類所有方法和屬性的完整文檔一直可以從Django官方文檔得到
參看http://www.djangoproject.com/documentation/syndication/
指定feed類型
默認框架使用RSS2.0生成feeds,這可以通過在你的Feed類添加feed_type屬性來更改:
- from django.utils.feedgenerator import Atom1Feed
- class MyFeed(Feed):
- feed_type = Atom1Feed
注意你設置feed_type為一個類對象,而不是一個實例,當前可以得到的feed類型為:
Feed class Format
django.utils.feedgenerator.Rss201rev2Feed RSS 2.01(default).
django.utils.feedgenerator.RssUser1and091Feed RSS 0.91.
django.utils.feedgenerator.Atom1Feed Atom 1.0.
封裝
為了指定封裝,如那些用來創建podcast feeds的,使用item_enclosure_url,item_enclosure_length和
item_enclosure_mime_type鉤子,例如:
- from myproject.models import Song
- class MyFeedWithEnclosures(MyFeed):
- title = "Example feed with enclosures"
- link = "/feeds/example-with-enclosures/"
- def items(self):
- return Song.objects.all()[:30]
- def item_enclosure_url(self, item):
- return item.song_url
- def item_enclosure_length(self, item):
- return item.song_length
- item_enclosure_mime_type = "audio/mpeg"
當然這個假設你已經用song_url域和song_length域(即bytes表示的size)創建了Song對象
語言
聚合框架創建的Feeds自動包含合適的(language)標簽(RSS 2.0)或者xml:lang屬性(Atom)
它直接來自于你的LANGUAGE_CODE設置
URL
link方法/屬性可以返回一個絕對URL(例如"/blog/")或者一個具有完整域名和協議的URL
(例如"http://www.example.com/blog/"),如果link不返回域名,則聚合框架將根據你的SITE_ID設置插入當前站點的域名
分別發布Atom和RSS feeds
一些開發者喜歡讓他們的feeds的Atom和RSS版本都可用,使用Django很容易做這個:只需創建你的feed類的子類并設置
feed_type為不同的東西,然后更新你的URL配置來添加額外的版本,這里是一個完整的例子:
- from django.contrib.syndication.feeds import Feed
- from chicagocrime.models import NewsItem
- from django.utils.feedgenerator import Atom1Feed
- class RssSiteNewsFeed(Feed):
- title = "Chicagocrime.org site news"
- link = "/sitenews/"
- description = "Updates on changes and additions to chicagocrime.org."
- def items(self):
- return NewsItem.objects.order_by('-pub_date')[:5]
- class AtomSiteNewsFeed(RssSiteNewsFeed):
- feed_type = Atom1Feed
然后相應的URL配置:
- from django.conf.urls.defaults import *
- from myproject.feeds import RssSiteNewsFeed, AtomSiteNewsFeed
- feeds = {
- 'rss': RssSiteNewsFeed,
- 'atom': AtomSiteNewsFeed,
- }
- urlpatterns = patterns('',
- # ...
- (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed',
- {'feed_dict': feeds}),
- # ...
- )
sitemap框架
類似于聚合框架,Django也有一個高級的Sitemap生成框架
一個Sitemap是一個你的網站的XML文件,它告訴搜索引擎索索引你的頁面的更新頻率和你的站點某些頁面聯系到其它頁面
有多"重要",這個信息幫助搜索引擎索引你的站點,參看http://www.sitemaps.org得到更多關于Sitemaps
Django的sitemap框架通過讓你用Python代碼表達這個信息來自動生成這個XML文件,為了創建一個sitemap,你只需寫
一個Sitemap類并在你的URL配置里指向它
安裝
遵循下面的步驟來安裝sitemap app:
1,添加'django.contrib.sitemaps'到你的INSTALLED_APPS設置
2,確認'django.template.loaders.app_directories.load_template_source'在你的TEMPLATE_LOADERS設置中
它默認在里面,所以如果你改變了這個設置則你將只需更改這個
3,確認你已經安裝了sites框架(參考第15章)
注意,sitemap程序不會安裝任何數據庫表,它需要進入INSTALLED_APPS的唯一的原因是為了讓load_template_source
模板載入器可以找到默認的模板
初始化
為了在你的Django站點激活sitemap生成,把下面的內容添加到你的URL配置里:
- (r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
這會告訴Django當一個客戶端訪問/sitemap.xml時構建一個sitemap
sitemap文件名不重要,但是位置很重要,搜索引擎將只為當前及以下的URL級別索引你的sitemap里的鏈接
例如,如果sitemap.xml存在于你的根目錄,它將引用你的站點的任何URL,如果sitemap存在于/content/sitemap.xml,
它將只引用以/content/開始的URL
sitemap使用一個額外的必需參數{'sitemaps': sitemaps},sitemaps應該是一個映射簡短的section標簽(如blog或者
news)到它的Sitemap類(如BlogSitemap或者NewsSitemap)的字典,它可能也映射一個Sitemap類的實例
(如BlogSitemap(some_var))
Sitemap類
一個Sitemap類是一個表示你的sitemap一部分條目的簡單的Python類,例如,一個Sitemap類可以表示你的博客的所有
條目,而另一個可以表示你的日程表的所有的事件
最簡單的情況下,所有這些部分混合在一個sitemap.xml里,但是也可以使用框架生成一個sitemap索引并引用單獨的
sitemap文件,每個部分一個文件(參看下面的內容)
Sitemap類必須繼承django.contrib.sitemaps.Sitemap,它們可以在你的代碼樹的任意位置
例如,讓我們假設你有一個博客系統和一個Entry模型,并且你想讓你的sitemap包含所有到你的單獨博客條目的鏈接
這里是你的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
在看過聚合框架之后,這將看起來非常熟悉:
1,changefreq和priority是對應(changefreq)和(priority)元素的類屬性,它們可以作為方法來調用,例如lastmod
2,items()是簡單的返回對象列表的方法,返回的對象將根據sitemap屬性(location,lastmod,changefreq和priority)
傳遞給任何可調用的方法
3,lastmod應該返回一個Python datetime對象
4,例子中沒有location方法,但是你可以為了指出你的對象的URL而提供它,默認location()對每個對象調用
get_absolute_url()并返回結果
Sitemap方法/屬性
像Feed類一樣,Sitemap成員可以是方法或者屬性,參考"復雜的例子"得到更多關于它怎樣工作的信息
一個Sitemap類可以定義以下方法/屬性:
items(必需)
提供對象列表,框架不關心它們是什么類型的對象,關心的只是這些對象傳遞給location(),lastmod(),changefreq()
和priority()方法
location(可選)
對給定對象提供絕對的URL
這里"絕對的URL"表示不包含協議和域名的URL,例如:
Good:'/foo/bar/'
Bad:'example.com/foo/bar/'
Bad:'http://example.com/foo/bar/'
如果location沒有提供,框架將對items()返回的每個對象調用get_absolute_url()方法
lastmod(可選)
對象的"last modification"日期,是一個Python datetime對象
changefreq(可選)
對象改變的頻率,可能的值(Sitemaps規范所給)為:
'always'
'hourly'
'daily'
'weekly'
'monthly'
'yearly'
'never'
priority(可選)
建議的索引優先級別,在0.0和1.0之間,一個頁面的默認級別為0.5,參看sitemaps.org文檔來得到更多關于priority
捷徑
sitemap框架為通常的情況提供了一些方便類:
FlatPageSitemap
django.contrib.sitemaps.FlatPageSitemap類查看當前站點定義的所有flat頁面并在sitemap里創建條目,這些條目只
包含location屬性,不包含lastmod,changefreq或priority,參考第15章來得到更多關于flat頁面
GenericSitemap
GenericSitemap類和你已經有的任何generic views(參考第9章)工作
為了使用它,創建一個實例并傳遞你傳遞給generic views的同樣的info_dict,僅有的需求是這個字典有一個queryset
條目,它可能也有一個date_field條目來指定從queryset得到的對象的date域,它被用于生成的sitemap的lastmod屬性
你也可以傳遞priority和changefreq關鍵字參數到GenericSitemap構造函數來為所有的URL指定這些屬性
這里是一個使用FlatPageSitemap和GenericSitemap的URL配置的例子(使用上面假定的Entry對象):
- 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 = {
-  
安徽新華電腦學校專業職業規劃師為你提供更多幫助【在線咨詢】