Django帶來了一個高級的聚合生成框架,它使得創建RSS和Atom feeds變得非常容易。
什么是RSS? 什么是Atom?
RSS和Atom都是基于XML的格式,你可以用它來提供有關你站點內容的自動更新的feed。 了解更多關于RSS的可以訪問 http://www.whatisrss.com/, 更多Atom的信息可以訪問 http://www.atomenabled.org/.
想創建一個聯合供稿的源(syndication feed),所需要做的只是寫一個簡短的python類。 你可以創建任意多的源(feed)。
高級feed生成框架是一個默認綁定到/feeds/的視圖,Django使用URL的其它部分(在/feeds/之后的任何東西)來決定輸出 哪個feed Django uses the remainder of the URL (everything after /feeds/ ) to determine which feed to return.
要創建一個 sitemap,你只需要寫一個 Sitemap 類然后配置你的URLconf指向它。
初始化
為了在您的Django站點中激活syndication feeds, 添加如下的 URLconf:
(r'^feeds/(?P.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds} ),
這一行告訴Django使用RSS框架處理所有的以 "feeds/" 開頭的URL. ( 你可以修改 "feeds/" 前綴以滿足您自己的要求. )
URLConf里有一行參數: {'feed_dict': feeds},這個參數可以把對應URL需要發布的feed內容傳遞給 syndication framework
特別的,feed_dict應該是一個映射feed的slug(簡短URL標簽)到它的Feed類的字典 你可以在URL配置本身里定義feed_dict,這里是一個完整的例子 You can define the feed_dict in the URLconf itself. Here's a full example URLconf:
from django.conf.urls.defaults import * from mysite.feeds import LatestEntries, LatestEntriesByCategory feeds = { 'latest': LatestEntries, 'categories': LatestEntriesByCategory, } urlpatterns = patterns('', # ... (r'^feeds/(?P.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}), # ... )
前面的例子注冊了兩個feed:
- ??? LatestEntries``表示的內容將對應到``feeds/latest/ .
- ??? LatestEntriesByCategory``的內容將對應到 ``feeds/categories/ .
以上的設定完成之后,接下來需要自己定義 Feed 類
一個 Feed 類是一個簡單的python類,用來表示一個syndication feed. 一個feed可能是簡單的 (例如一個站點新聞feed,或者最基本的,顯示一個blog的最新條目),也可能更加復雜(例如一個顯示blog某一類別下所有條目的feed。 這里類別 category 是個變量).
Feed類必須繼承django.contrib.syndication.feeds.Feed,它們可以在你的代碼樹的任何位置
一個簡單的Feed
This simple example describes a feed of the latest five blog entries for a given blog: from django.contrib.syndication.feeds import Feed from mysite.blog.models import Entry class LatestEntries(Feed): title = "My Blog" link = "/archive/" description = "The latest news about stuff." def items(self): return Entry.objects.order_by('-pub_date')[:5]
要注意的重要的事情如下所示:
- ??? 子類 django.contrib.syndication.feeds.Feed .
- ??? title , link , 和 description 對應一個標準 RSS 里的
-
??? items() 是一個方法,返回一個用以包含在包含在feed的
- 元素里的 list 雖然例子里用Djangos database API返回的 NewsItem 對象, items() 不一定必須返回 model的實例 Although this example returns Entry objects using Django's database API, items() doesn't have to return model instances.
還有一個步驟,在一個RSS feed里,每個(item)有一個(title),(link)和(description),我們需要告訴框架 把數據放到這些元素中 In an RSS feed, each
??? 如果要指定
??? RSS系統模板渲染每一個條目,需要給傳遞2個參數給模板上下文變量:
- ??????? obj : 當前對象 ( 返回到 items() 任意對象之一 )。
- ??????? site : 一個表示當前站點的 django.models.core.sites.Site 對象。 這對于 {{ site.domain }} 或者 {{ site.name }} 很有用。
??? 如果你在創建模板的時候,沒有指明標題或者描述信息,框架會默認使用 "{{ obj }}" ,對象的字符串表示。 (For model objects, this will be the __unicode__() method.
??? 你也可以通過修改 Feed 類中的兩個屬性 title_template 和 description_template 來改變這兩個模板的名字。
??? 你有兩種方法來指定 的內容。 Django 首先執行 items() 中每一項的 get_absolute_url() 方法。 如果該方法不存在,就會嘗試執行 Feed 類中的 item_link() 方法,并將自身作為 item 參數傳遞進去。
??? get_absolute_url() 和 item_link() 都應該以Python字符串形式返回URL。
??? 對于前面提到的 LatestEntries 例子,我們可以實現一個簡單的feed模板。 latest_title.html 包括:
{{ obj.title }}
??? 并且 latest_description.html 包含:
{{ obj.description }}
??? 這真是 太 簡單了!
一個更復雜的Feed
框架通過參數支持更加復雜的feeds。
For example, say your blog offers an RSS feed for every distinct tag you've used to categorize your entries. 如果為每一個單獨的區域建立一個 Feed 類就顯得很不明智。
取而代之的方法是,使用聚合框架來產生一個通用的源,使其可以根據feeds URL返回相應的信息。
Your tag-specific feeds could use URLs like this:
??? http://example.com/feeds/tags/python/ : Returns recent entries tagged with python
??? http://example.com/feeds/tags/cats/ : Returns recent entries tagged with cats
固定的那一部分是 "beats" (區域)。
舉個例子會澄清一切。 下面是每個地區特定的feeds:
from django.core.exceptions import ObjectDoesNotExist from mysite.blog.models import Entry, Tag class TagFeed(Feed): def get_object(self, bits): # In case of "/feeds/tags/cats/dogs/mice/", or other such # clutter, check that bits has only one member. if len(bits) != 1: raise ObjectDoesNotExist return Tag.objects.get(tag=bits[0]) def title(self, obj): return "My Blog: Entries tagged with %s" % obj.tag def link(self, obj): return obj.get_absolute_url() def description(self, obj): return "Entries tagged with %s" % obj.tag def items(self, obj): entries = Entry.objects.filter(tags__id__exact=obj.id) return entries.order_by('-pub_date')[:30]
以下是RSS框架的基本算法,我們假設通過URL /rss/beats/0613/ 來訪問這個類:
??? 框架獲得了URL /rss/beats/0613/ 并且注意到URL中的slug部分后面含有更多的信息。 它將斜杠("/" )作為分隔符,把剩余的字符串分割開作為參數,調用 Feed 類的 get_object() 方法。
??? 在這個例子中,添加的信息是 ['0613'] 。對于 /rss/beats/0613/foo/bar/ 的一個URL請求, 這些信息就是 ['0613', 'foo', 'bar'] 。
??? get_object() 就根據給定的 bits 值來返回區域信息。
??? In this case, it uses the Django database API to retrieve the Tag . Note that get_object() should raise django.core.exceptions.ObjectDoesNotExist if given invalid parameters. 在 Beat.objects.get() 調用中也沒有出現 try /except 代碼塊。 函數在出錯時拋出 Beat.DoesNotExist 異常,而 Beat.DoesNotExist 是 ObjectDoesNotExist 異常的一個子類型。
??? 為產生
??????? 試圖調用一個函數,并且以 get_object() 返回的對象作為參數傳遞給 obj 參數。
??????? 如果沒有成功,則不帶參數調用一個方法。
??????? 還不成功,則使用類屬性。
??? 最后,值得注意的是,這個例子中的 items() 使用 obj 參數。 對于 items 的算法就如同上面第一步所描述的那樣,首先嘗試 items(obj) , 然后是 items() ,最后是 items 類屬性(必須是一個列表)。
Feed 類所有方法和屬性的完整文檔,請參考官方的Django文檔 (http://www.djangoproject.com/documentation/0.96/syndication_feeds/) 。
指定Feed的類型
默認情況下, 聚合框架生成RSS 2.0. 要改變這樣的情況, 在 Feed 類中添加一個 feed_type 屬性. To change that, add a feed_type attribute to your Feed class:
from django.utils.feedgenerator import Atom1Feed class MyFeed(Feed): feed_type = Atom1Feed
注意你把 feed_type 賦值成一個類對象,而不是類實例。 目前合法的Feed類型如表所示。
閉包
為了指定閉包(例如,與feed項比方說MP3 feeds相關聯的媒體資源信息),使用 item_enclosure_url , item_enclosure_length , 以及 item_enclosure_mime_type ,比如
from myproject.models import Song class MyFeedWithEnclosures(Feed): 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 (比如按照字節計算的長度)域的 Song 對象。
語言
聚合框架自動創建的Feed包含適當的
URLs
link 方法/屬性可以以絕對URL的形式(例如, "/blog/" )或者指定協議和域名的URL的形式返回(例如 "http://www.example.com/blog/" )。如果 link 沒有返回域名,聚合框架會根據 SITE_ID 設置,自動的插入當前站點的域信息。 (See Chapter 16 for more on SITE_ID and the sites framework.)
Atom feeds需要
指明feeds現在的位置。 The syndication framework populates this automatically.
同時發布Atom and RSS
一些開發人員想 同時 支持Atom和RSS。 這在Django中很容易實現: 只需創建一個你的 feed 類的子類,然后修改 feed_type ,并且更新URLconf內容。 下面是一個完整的例子: Here's a full example:
from django.contrib.syndication.feeds import Feed from django.utils.feedgenerator import Atom1Feed from mysite.blog.models import Entry class RssLatestEntries(Feed): title = "My Blog" link = "/archive/" description = "The latest news about stuff." def items(self): return Entry.objects.order_by('-pub_date')[:5] class AtomLatestEntries(RssLatestEntries): feed_type = Atom1Feed
這是與之相對應那個的URLconf:
from django.conf.urls.defaults import * from myproject.feeds import RssLatestEntries, AtomLatestEntries feeds = { 'rss': RssLatestEntries, 'atom': AtomLatestEntries, } urlpatterns = patterns('', # ... (r'^feeds/(?P.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}), # ... )
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
