用Python的Django架構來製作一個RSS閱讀器

來源:互聯網
上載者:User
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, LatestEntriesByCategoryfeeds = {  'latest': LatestEntries,  'categories': LatestEntriesByCategory,}urlpatterns = patterns('',  # ...  (r'^feeds/(?P.*)/$', 'django.contrib.syndication.views.feed',    {'feed_dict': feeds}),  # ...)

前面的例子註冊了兩個feed:

  1. LatestEntries``表示的內容將對應到``feeds/latest/ .
  2. 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 Feedfrom mysite.blog.models import Entryclass 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 has a , , and . We need to tell the framework what data to put into those elements.

如果要指定 和 ,可以建立一個Django模板(見Chapter 4)名字叫 feeds/latest_title.html 和 feeds/latest_description.html ,後者是URLConf裡為對應feed指定的 slug 。注意 .html 尾碼是必須的。 Note that the .html extension is required.

RSS系統模板渲染每一個條目,需要給傳遞2個參數給模板上下文變數:

  1. obj : 當前對象 ( 返回到 items() 任意對象之一 )。
  2. 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 ObjectDoesNotExistfrom mysite.blog.models import Entry, Tagclass 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 異常的一個子類型。

為產生 , , 和 的feeds, Django使用 title() , link() , 和 description() 方法。 在上面的例子中,它們都是簡單的字串類型的類屬性,而這個例子表明,它們既可以是字串, 也可以是 方法。 對於每一個 title , link 和 description 的組合,Django使用以下的演算法:

試圖調用一個函數,並且以 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 Atom1Feedclass 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 Songclass 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包含適當的 標籤(RSS 2.0) 或 xml:lang 屬性(Atom). 他直接來自於您的 LANGUAGE_CODE 設定. This comes directly from your LANGUAGE_CODE setting.
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 Feedfrom django.utils.feedgenerator import Atom1Feedfrom mysite.blog.models import Entryclass 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, AtomLatestEntriesfeeds = {  'rss': RssLatestEntries,  'atom': AtomLatestEntries,}urlpatterns = patterns('',  # ...  (r'^feeds/(?P.*)/$', 'django.contrib.syndication.views.feed',    {'feed_dict': feeds}),  # ...)
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.