聯合內容訂閱框架

Django 提供了一個高階的聯合內容訂閱產生框架,用於建立 RSSAtom 訂閱。

要建立任何聯合內容訂閱,您所要做的就是編寫一個簡短的 Python 類別。您可以建立任意數量的訂閱。

Django 還提供一個低階的訂閱產生 API。如果您想在 Web 環境之外或以其他低階方式產生訂閱,請使用此 API。

高階框架

概觀

高階訂閱產生框架由 Feed 類別提供。要建立一個訂閱,請編寫一個 Feed 類別,並在您的 URLconf 中指向它的實例。

Feed 類別

Feed 類別是一個代表聯合內容訂閱的 Python 類別。訂閱可以很簡單(例如,「網站新聞」訂閱,或顯示部落格最新條目的基本訂閱),也可以更複雜(例如,顯示特定類別中所有部落格條目的訂閱,其中類別是可變的)。

Feed 類別是 django.contrib.syndication.views.Feed 的子類別。它們可以存在於您的程式碼庫中的任何位置。

Feed 類別的實例是可以在您的 URLconf 中使用的檢視。

一個簡單的範例

這個簡單的範例,取自一個假設的警察巡邏新聞網站,描述了最近五個新聞項目的訂閱

from django.contrib.syndication.views import Feed
from django.urls import reverse
from policebeat.models import NewsItem


class LatestEntriesFeed(Feed):
    title = "Police beat site news"
    link = "/sitenews/"
    description = "Updates on changes and additions to police beat central."

    def items(self):
        return NewsItem.objects.order_by("-pub_date")[:5]

    def item_title(self, item):
        return item.title

    def item_description(self, item):
        return item.description

    # item_link is only needed if NewsItem has no get_absolute_url method.
    def item_link(self, item):
        return reverse("news-item", args=[item.pk])

要將 URL 連接到此訂閱,請將 Feed 物件的實例放入您的 URLconf 中。例如

from django.urls import path
from myproject.feeds import LatestEntriesFeed

urlpatterns = [
    # ...
    path("latest/feed/", LatestEntriesFeed()),
    # ...
]

注意

  • Feed 類別是 django.contrib.syndication.views.Feed 的子類別。

  • titlelinkdescription 分別對應到標準的 RSS <title><link><description> 元素。

  • items() 是一個方法,它會傳回一個物件列表,這些物件應以 <item> 元素的形式包含在訂閱中。儘管此範例使用 Django 的 物件關聯對應器 傳回 NewsItem 物件,但 items() 不必傳回模型實例。儘管使用 Django 模型可以「免費」獲得一些功能,但 items() 可以傳回您想要的任何類型的物件。

  • 如果您建立的是 Atom 訂閱而不是 RSS 訂閱,請設定 subtitle 屬性而不是 description 屬性。有關範例,請參閱稍後的同時發佈 Atom 和 RSS 訂閱

還有一件事要做。在 RSS 訂閱中,每個 <item> 都有一個 <title><link><description>。我們需要告訴框架將哪些資料放入這些元素。

  • 對於 <title><description> 的內容,Django 會嘗試在 Feed 類別上呼叫方法 item_title()item_description()。它們會傳遞一個單一參數,item,即物件本身。這些是可選的;預設情況下,物件的字串表示形式會同時用於兩者。

    如果您想為標題或描述進行任何特殊格式設定,可以使用 Django 範本。它們的路徑可以使用 Feed 類別上的 title_templatedescription_template 屬性來指定。範本會針對每個項目進行呈現,並傳遞兩個範本內容變數

    請參閱下方一個複雜的範例,其中使用了描述範本。

    Feed.get_context_data(**kwargs)

    如果您需要提供比之前提到的兩個變數更多的資訊,也可以將額外的資訊傳遞給標題和描述範本。您可以在 Feed 子類別中提供您自己的 get_context_data 方法實作。例如

    from mysite.models import Article
    from django.contrib.syndication.views import Feed
    
    
    class ArticlesFeed(Feed):
        title = "My articles"
        description_template = "feeds/articles.html"
    
        def items(self):
            return Article.objects.order_by("-pub_date")[:5]
    
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context["foo"] = "bar"
            return context
    

    以及範本

    Something about {{ foo }}: {{ obj.description }}
    

    此方法會針對 items() 傳回的列表中的每個項目呼叫一次,並帶有以下關鍵字引數

    • item:目前的項目。出於回溯相容性的原因,此內容變數的名稱為 {{ obj }}

    • objget_object() 傳回的物件。預設情況下,這不會公開給範本,以避免與 {{ obj }}(請參閱上方)混淆,但您可以在 get_context_data() 的實作中使用它。

    • site:如上所述的目前網站。

    • request:目前的請求。

    get_context_data() 的行為模仿 通用檢視 的行為 - 您應該呼叫 super() 從父類別擷取內容資料,新增您的資料並傳回修改過的字典。

  • 要指定 <link> 的內容,您有兩個選項。對於 items() 中的每個項目,Django 首先會嘗試在 Feed 類別上呼叫 item_link() 方法。與標題和描述類似,它會傳遞一個單一參數,item。如果該方法不存在,Django 會嘗試在該物件上執行 get_absolute_url() 方法。get_absolute_url()item_link() 都應以一般 Python 字串的形式傳回項目的 URL。與 get_absolute_url() 一樣,item_link() 的結果會直接包含在 URL 中,因此您有責任在方法本身中完成所有必要的 URL 引號和轉換為 ASCII 的工作。

一個複雜的範例

此框架也透過參數支援更複雜的 feed。

例如,一個網站可以針對城市中每個警察巡邏區提供最近犯罪事件的 RSS feed。為每個警察巡邏區創建一個單獨的 Feed 類別是很愚蠢的;這會違反 DRY 原則,並且會將資料耦合到程式邏輯。相反地,聯合訂閱框架允許您存取從 URLconf 傳遞的參數,以便 feed 可以根據 feed 的 URL 中的資訊輸出項目。

警察巡邏區的 feed 可以透過像這樣的 URL 存取

  • /beats/613/rss/ – 返回巡邏區 613 最近的犯罪事件。

  • /beats/1424/rss/ – 返回巡邏區 1424 最近的犯罪事件。

這些可以使用像這樣的 URLconf 行來匹配

path("beats/<int:beat_id>/rss/", BeatFeed()),

就像 view 一樣,URL 中的參數會連同請求物件一起傳遞給 get_object() 方法。

以下是這些特定巡邏區 feed 的程式碼

from django.contrib.syndication.views import Feed


class BeatFeed(Feed):
    description_template = "feeds/beat_description.html"

    def get_object(self, request, beat_id):
        return Beat.objects.get(pk=beat_id)

    def title(self, obj):
        return "Police beat central: 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):
        return Crime.objects.filter(beat=obj).order_by("-crime_date")[:30]

為了產生 feed 的 <title><link><description>,Django 使用 title()link()description() 方法。在先前的範例中,它們是字串類別屬性,但此範例說明它們可以是字串方法。對於每個 titlelinkdescription,Django 遵循此演算法

  • 首先,它嘗試呼叫方法,傳遞 obj 參數,其中 obj 是由 get_object() 返回的物件。

  • 如果失敗,它會嘗試呼叫不帶參數的方法。

  • 如果失敗,它會使用類別屬性。

另請注意,items() 也遵循相同的演算法 – 首先,它嘗試 items(obj),然後是 items(),最後是 items 類別屬性(應該是列表)。

我們正在使用範本來描述項目。它可以像這樣簡單

{{ obj.description }}

但是,您可以自由地新增所需的格式。

下面的 ExampleFeed 類別提供了關於 Feed 類別的方法和屬性的完整文件。

指定 feed 的類型

預設情況下,此框架中產生的 feed 使用 RSS 2.0。

若要變更此設定,請將 feed_type 屬性新增至您的 Feed 類別,如下所示

from django.utils.feedgenerator import Atom1Feed


class MyFeed(Feed):
    feed_type = Atom1Feed

請注意,您將 feed_type 設定為類別物件,而不是執行個體。

目前可用的 feed 類型有

附件

若要指定附件(例如用於建立 podcast feed 的附件),請使用 item_enclosures hook,或者,如果每個項目只有一個附件,則使用 item_enclosure_urlitem_enclosure_lengthitem_enclosure_mime_type hook。請參閱下面的 ExampleFeed 類別以取得使用範例。

語言

聯合訂閱框架建立的 feed 會自動包含適當的 <language> 標籤 (RSS 2.0) 或 xml:lang 屬性 (Atom)。預設情況下,這是 django.utils.translation.get_language()。您可以透過設定 language 類別屬性來變更它。

URL

link 方法/屬性可以傳回絕對路徑(例如 "/blog/")或具有完整網域和協定的 URL(例如 "https://www.example.com/blog/")。如果 link 沒有傳回網域,則聯合訂閱框架將根據您的 SITE_ID 設定插入目前網站的網域。

Atom feed 需要 <link rel="self"> 來定義 feed 的目前位置。聯合訂閱框架會根據 SITE_ID 設定使用目前網站的網域自動填入此設定。

同時發佈 Atom 和 RSS feed

有些開發人員喜歡同時提供其 feed 的 AtomRSS 版本。若要執行此操作,您可以建立 Feed 類別的子類別,並將 feed_type 設定為不同的類型。然後更新您的 URLconf 以新增額外的版本。

以下是一個完整的範例

from django.contrib.syndication.views import Feed
from policebeat.models import NewsItem
from django.utils.feedgenerator import Atom1Feed


class RssSiteNewsFeed(Feed):
    title = "Police beat site news"
    link = "/sitenews/"
    description = "Updates on changes and additions to police beat central."

    def items(self):
        return NewsItem.objects.order_by("-pub_date")[:5]


class AtomSiteNewsFeed(RssSiteNewsFeed):
    feed_type = Atom1Feed
    subtitle = RssSiteNewsFeed.description

注意

在此範例中,RSS feed 使用 description,而 Atom feed 使用 subtitle。這是因為 Atom feed 沒有提供 feed 層級的「description」,但它們確實提供「subtitle」。

如果您在 Feed 類別中提供 description,Django 將不會自動將其放入 subtitle 元素中,因為 subtitle 和 description 不一定相同。相反地,您應該定義 subtitle 屬性。

在上面的範例中,我們將 Atom feed 的 subtitle 設定為 RSS feed 的 description,因為它已經很短了。

以及隨附的 URLconf

from django.urls import path
from myproject.feeds import AtomSiteNewsFeed, RssSiteNewsFeed

urlpatterns = [
    # ...
    path("sitenews/rss/", RssSiteNewsFeed()),
    path("sitenews/atom/", AtomSiteNewsFeed()),
    # ...
]

Feed 類別參考

class views.Feed

此範例說明 Feed 類別的所有可能屬性和方法

from django.contrib.syndication.views import Feed
from django.utils import feedgenerator


class ExampleFeed(Feed):
    # FEED TYPE -- Optional. This should be a class that subclasses
    # django.utils.feedgenerator.SyndicationFeed. This designates
    # which type of feed this should be: RSS 2.0, Atom 1.0, etc. If
    # you don't specify feed_type, your feed will be RSS 2.0. This
    # should be a class, not an instance of the class.

    feed_type = feedgenerator.Rss201rev2Feed

    # TEMPLATE NAMES -- Optional. These should be strings
    # representing names of Django templates that the system should
    # use in rendering the title and description of your feed items.
    # Both are optional. If a template is not specified, the
    # item_title() or item_description() methods are used instead.

    title_template = None
    description_template = None

    # LANGUAGE -- Optional. This should be a string specifying a language
    # code. Defaults to django.utils.translation.get_language().
    language = "de"

    # TITLE -- One of the following three is required. The framework
    # looks for them in this order.

    def title(self, obj):
        """
        Takes the object returned by get_object() and returns the
        feed's title as a normal Python string.
        """

    def title(self):
        """
        Returns the feed's title as a normal Python string.
        """

    title = "foo"  # Hard-coded title.

    # LINK -- One of the following three is required. The framework
    # looks for them in this order.

    def link(self, obj):
        """
        # Takes the object returned by get_object() and returns the URL
        # of the HTML version of the feed as a normal Python string.
        """

    def link(self):
        """
        Returns the URL of the HTML version of the feed as a normal Python
        string.
        """

    link = "/blog/"  # Hard-coded URL.

    # FEED_URL -- One of the following three is optional. The framework
    # looks for them in this order.

    def feed_url(self, obj):
        """
        # Takes the object returned by get_object() and returns the feed's
        # own URL as a normal Python string.
        """

    def feed_url(self):
        """
        Returns the feed's own URL as a normal Python string.
        """

    feed_url = "/blog/rss/"  # Hard-coded URL.

    # GUID -- One of the following three is optional. The framework looks
    # for them in this order. This property is only used for Atom feeds
    # (where it is the feed-level ID element). If not provided, the feed
    # link is used as the ID.

    def feed_guid(self, obj):
        """
        Takes the object returned by get_object() and returns the globally
        unique ID for the feed as a normal Python string.
        """

    def feed_guid(self):
        """
        Returns the feed's globally unique ID as a normal Python string.
        """

    feed_guid = "/foo/bar/1234"  # Hard-coded guid.

    # DESCRIPTION -- One of the following three is required. The framework
    # looks for them in this order.

    def description(self, obj):
        """
        Takes the object returned by get_object() and returns the feed's
        description as a normal Python string.
        """

    def description(self):
        """
        Returns the feed's description as a normal Python string.
        """

    description = "Foo bar baz."  # Hard-coded description.

    # AUTHOR NAME --One of the following three is optional. The framework
    # looks for them in this order.

    def author_name(self, obj):
        """
        Takes the object returned by get_object() and returns the feed's
        author's name as a normal Python string.
        """

    def author_name(self):
        """
        Returns the feed's author's name as a normal Python string.
        """

    author_name = "Sally Smith"  # Hard-coded author name.

    # AUTHOR EMAIL --One of the following three is optional. The framework
    # looks for them in this order.

    def author_email(self, obj):
        """
        Takes the object returned by get_object() and returns the feed's
        author's email as a normal Python string.
        """

    def author_email(self):
        """
        Returns the feed's author's email as a normal Python string.
        """

    author_email = "test@example.com"  # Hard-coded author email.

    # AUTHOR LINK --One of the following three is optional. The framework
    # looks for them in this order. In each case, the URL should include
    # the scheme (such as "https://") and domain name.

    def author_link(self, obj):
        """
        Takes the object returned by get_object() and returns the feed's
        author's URL as a normal Python string.
        """

    def author_link(self):
        """
        Returns the feed's author's URL as a normal Python string.
        """

    author_link = "https://www.example.com/"  # Hard-coded author URL.

    # CATEGORIES -- One of the following three is optional. The framework
    # looks for them in this order. In each case, the method/attribute
    # should return an iterable object that returns strings.

    def categories(self, obj):
        """
        Takes the object returned by get_object() and returns the feed's
        categories as iterable over strings.
        """

    def categories(self):
        """
        Returns the feed's categories as iterable over strings.
        """

    categories = ["python", "django"]  # Hard-coded list of categories.

    # COPYRIGHT NOTICE -- One of the following three is optional. The
    # framework looks for them in this order.

    def feed_copyright(self, obj):
        """
        Takes the object returned by get_object() and returns the feed's
        copyright notice as a normal Python string.
        """

    def feed_copyright(self):
        """
        Returns the feed's copyright notice as a normal Python string.
        """

    feed_copyright = "Copyright (c) 2007, Sally Smith"  # Hard-coded copyright notice.

    # TTL -- One of the following three is optional. The framework looks
    # for them in this order. Ignored for Atom feeds.

    def ttl(self, obj):
        """
        Takes the object returned by get_object() and returns the feed's
        TTL (Time To Live) as a normal Python string.
        """

    def ttl(self):
        """
        Returns the feed's TTL as a normal Python string.
        """

    ttl = 600  # Hard-coded Time To Live.

    # ITEMS -- One of the following three is required. The framework looks
    # for them in this order.

    def items(self, obj):
        """
        Takes the object returned by get_object() and returns a list of
        items to publish in this feed.
        """

    def items(self):
        """
        Returns a list of items to publish in this feed.
        """

    items = ["Item 1", "Item 2"]  # Hard-coded items.

    # GET_OBJECT -- This is required for feeds that publish different data
    # for different URL parameters. (See "A complex example" above.)

    def get_object(self, request, *args, **kwargs):
        """
        Takes the current request and the arguments from the URL, and
        returns an object represented by this feed. Raises
        django.core.exceptions.ObjectDoesNotExist on error.
        """

    # ITEM TITLE AND DESCRIPTION -- If title_template or
    # description_template are not defined, these are used instead. Both are
    # optional, by default they will use the string representation of the
    # item.

    def item_title(self, item):
        """
        Takes an item, as returned by items(), and returns the item's
        title as a normal Python string.
        """

    def item_title(self):
        """
        Returns the title for every item in the feed.
        """

    item_title = "Breaking News: Nothing Happening"  # Hard-coded title.

    def item_description(self, item):
        """
        Takes an item, as returned by items(), and returns the item's
        description as a normal Python string.
        """

    def item_description(self):
        """
        Returns the description for every item in the feed.
        """

    item_description = "A description of the item."  # Hard-coded description.

    def get_context_data(self, **kwargs):
        """
        Returns a dictionary to use as extra context if either
        description_template or item_template are used.

        Default implementation preserves the old behavior
        of using {'obj': item, 'site': current_site} as the context.
        """

    # ITEM LINK -- One of these three is required. The framework looks for
    # them in this order.

    # First, the framework tries the two methods below, in
    # order. Failing that, it falls back to the get_absolute_url()
    # method on each item returned by items().

    def item_link(self, item):
        """
        Takes an item, as returned by items(), and returns the item's URL.
        """

    def item_link(self):
        """
        Returns the URL for every item in the feed.
        """

    # ITEM_GUID -- The following method is optional. If not provided, the
    # item's link is used by default.

    def item_guid(self, obj):
        """
        Takes an item, as return by items(), and returns the item's ID.
        """

    # ITEM_GUID_IS_PERMALINK -- The following method is optional. If
    # provided, it sets the 'isPermaLink' attribute of an item's
    # GUID element. This method is used only when 'item_guid' is
    # specified.

    def item_guid_is_permalink(self, obj):
        """
        Takes an item, as returned by items(), and returns a boolean.
        """

    item_guid_is_permalink = False  # Hard coded value

    # ITEM AUTHOR NAME -- One of the following three is optional. The
    # framework looks for them in this order.

    def item_author_name(self, item):
        """
        Takes an item, as returned by items(), and returns the item's
        author's name as a normal Python string.
        """

    def item_author_name(self):
        """
        Returns the author name for every item in the feed.
        """

    item_author_name = "Sally Smith"  # Hard-coded author name.

    # ITEM AUTHOR EMAIL --One of the following three is optional. The
    # framework looks for them in this order.
    #
    # If you specify this, you must specify item_author_name.

    def item_author_email(self, obj):
        """
        Takes an item, as returned by items(), and returns the item's
        author's email as a normal Python string.
        """

    def item_author_email(self):
        """
        Returns the author email for every item in the feed.
        """

    item_author_email = "test@example.com"  # Hard-coded author email.

    # ITEM AUTHOR LINK -- One of the following three is optional. The
    # framework looks for them in this order. In each case, the URL should
    # include the scheme (such as "https://") and domain name.
    #
    # If you specify this, you must specify item_author_name.

    def item_author_link(self, obj):
        """
        Takes an item, as returned by items(), and returns the item's
        author's URL as a normal Python string.
        """

    def item_author_link(self):
        """
        Returns the author URL for every item in the feed.
        """

    item_author_link = "https://www.example.com/"  # Hard-coded author URL.

    # ITEM ENCLOSURES -- One of the following three is optional. The
    # framework looks for them in this order. If one of them is defined,
    # ``item_enclosure_url``, ``item_enclosure_length``, and
    # ``item_enclosure_mime_type`` will have no effect.

    def item_enclosures(self, item):
        """
        Takes an item, as returned by items(), and returns a list of
        ``django.utils.feedgenerator.Enclosure`` objects.
        """

    def item_enclosures(self):
        """
        Returns the ``django.utils.feedgenerator.Enclosure`` list for every
        item in the feed.
        """

    item_enclosures = []  # Hard-coded enclosure list

    # ITEM ENCLOSURE URL -- One of these three is required if you're
    # publishing enclosures and you're not using ``item_enclosures``. The
    # framework looks for them in this order.

    def item_enclosure_url(self, item):
        """
        Takes an item, as returned by items(), and returns the item's
        enclosure URL.
        """

    def item_enclosure_url(self):
        """
        Returns the enclosure URL for every item in the feed.
        """

    item_enclosure_url = "/foo/bar.mp3"  # Hard-coded enclosure link.

    # ITEM ENCLOSURE LENGTH -- One of these three is required if you're
    # publishing enclosures and you're not using ``item_enclosures``. The
    # framework looks for them in this order. In each case, the returned
    # value should be either an integer, or a string representation of the
    # integer, in bytes.

    def item_enclosure_length(self, item):
        """
        Takes an item, as returned by items(), and returns the item's
        enclosure length.
        """

    def item_enclosure_length(self):
        """
        Returns the enclosure length for every item in the feed.
        """

    item_enclosure_length = 32000  # Hard-coded enclosure length.

    # ITEM ENCLOSURE MIME TYPE -- One of these three is required if you're
    # publishing enclosures and you're not using ``item_enclosures``. The
    # framework looks for them in this order.

    def item_enclosure_mime_type(self, item):
        """
        Takes an item, as returned by items(), and returns the item's
        enclosure MIME type.
        """

    def item_enclosure_mime_type(self):
        """
        Returns the enclosure MIME type for every item in the feed.
        """

    item_enclosure_mime_type = "audio/mpeg"  # Hard-coded enclosure MIME type.

    # ITEM PUBDATE -- It's optional to use one of these three. This is a
    # hook that specifies how to get the pubdate for a given item.
    # In each case, the method/attribute should return a Python
    # datetime.datetime object.

    def item_pubdate(self, item):
        """
        Takes an item, as returned by items(), and returns the item's
        pubdate.
        """

    def item_pubdate(self):
        """
        Returns the pubdate for every item in the feed.
        """

    item_pubdate = datetime.datetime(2005, 5, 3)  # Hard-coded pubdate.

    # ITEM UPDATED -- It's optional to use one of these three. This is a
    # hook that specifies how to get the updateddate for a given item.
    # In each case, the method/attribute should return a Python
    # datetime.datetime object.

    def item_updateddate(self, item):
        """
        Takes an item, as returned by items(), and returns the item's
        updateddate.
        """

    def item_updateddate(self):
        """
        Returns the updateddate for every item in the feed.
        """

    item_updateddate = datetime.datetime(2005, 5, 3)  # Hard-coded updateddate.

    # ITEM CATEGORIES -- It's optional to use one of these three. This is
    # a hook that specifies how to get the list of categories for a given
    # item. In each case, the method/attribute should return an iterable
    # object that returns strings.

    def item_categories(self, item):
        """
        Takes an item, as returned by items(), and returns the item's
        categories.
        """

    def item_categories(self):
        """
        Returns the categories for every item in the feed.
        """

    item_categories = ["python", "django"]  # Hard-coded categories.

    # ITEM COPYRIGHT NOTICE (only applicable to Atom feeds) -- One of the
    # following three is optional. The framework looks for them in this
    # order.

    def item_copyright(self, obj):
        """
        Takes an item, as returned by items(), and returns the item's
        copyright notice as a normal Python string.
        """

    def item_copyright(self):
        """
        Returns the copyright notice for every item in the feed.
        """

    item_copyright = "Copyright (c) 2007, Sally Smith"  # Hard-coded copyright notice.

    # ITEM COMMENTS URL -- It's optional to use one of these three. This is
    # a hook that specifies how to get the URL of a page for comments for a
    # given item.

    def item_comments(self, obj):
        """
        Takes an item, as returned by items(), and returns the item's
        comments URL as a normal Python string.
        """

    def item_comments(self):
        """
        Returns the comments URL for every item in the feed.
        """

    item_comments = "https://www.example.com/comments"  # Hard-coded comments URL

底層框架

在幕後,高階 RSS 框架使用低階框架來產生 feed 的 XML。此框架位於單一模組中:django/utils/feedgenerator.py

您可以在您自己的程式碼中使用此框架,以進行較低階的 feed 產生。您也可以建立自訂的 feed 產生器子類別,以便與 feed_type Feed 選項搭配使用。

SyndicationFeed 類別

feedgenerator 模組包含一個基礎類別

以及數個子類別

這三個類別中的每一個都知道如何將特定類型的 feed 呈現為 XML。它們共用此介面

SyndicationFeed.__init__()

使用給定的中繼資料字典初始化 feed,該中繼資料適用於整個 feed。必要的關鍵字引數為

  • title

  • link

  • description

還有許多其他可選關鍵字

  • language

  • author_email

  • author_name

  • author_link

  • subtitle

  • categories

  • feed_url

  • feed_copyright

  • feed_guid

  • ttl

任何傳遞給 __init__ 的額外關鍵字參數都會儲存在 self.feed 中,以供自訂 Feed 產生器使用。

除了 categories 應為字串序列之外,所有參數都應為字串。請注意,某些控制字元在 XML 文件中是不允許的。如果您的內容中包含這些字元,在產生 Feed 時可能會遇到 ValueError

SyndicationFeed.add_item()

使用給定的參數向 Feed 新增一個項目。

必要關鍵字參數為

  • title

  • link

  • description

可選關鍵字參數為

  • author_email

  • author_name

  • author_link

  • pubdate

  • comments

  • unique_id

  • enclosures

  • categories

  • item_copyright

  • ttl

  • updateddate

額外的關鍵字參數將被儲存,以供自訂 Feed 產生器使用。

如果提供,所有參數都應為字串,除了:

SyndicationFeed.write()

以給定的編碼將 Feed 輸出到 outfile,其為類似檔案的物件。

SyndicationFeed.writeString()

以給定的編碼將 Feed 作為字串返回。

例如,要建立一個 Atom 1.0 Feed 並將其列印到標準輸出

>>> from django.utils import feedgenerator
>>> from datetime import datetime
>>> f = feedgenerator.Atom1Feed(
...     title="My Blog",
...     link="https://www.example.com/",
...     description="In which I write about what I ate today.",
...     language="en",
...     author_name="Myself",
...     feed_url="https://example.com/atom.xml",
... )
>>> f.add_item(
...     title="Hot dog today",
...     link="https://www.example.com/entries/1/",
...     pubdate=datetime.now(),
...     description="<p>Today I had a Vienna Beef hot dog. It was pink, plump and perfect.</p>",
... )
>>> print(f.writeString("UTF-8"))
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
...
</feed>

自訂 Feed 產生器

如果您需要產生自訂的 Feed 格式,您有幾種選擇。

如果 Feed 格式是完全自訂的,您會需要繼承 SyndicationFeed 並完全取代 write()writeString() 方法。

但是,如果 Feed 格式是 RSS 或 Atom 的衍生格式(例如,GeoRSS、Apple 的 iTunes podcast 格式等),您有更好的選擇。這些類型的 Feed 通常會將額外的元素和/或屬性新增到基礎格式中,並且 SyndicationFeed 會呼叫一組方法來取得這些額外的屬性。因此,您可以繼承適當的 Feed 產生器類別(Atom1FeedRss201rev2Feed)並擴充這些回呼。它們是:

SyndicationFeed.root_attributes(self)

傳回一個 dict,其中包含要新增到根 Feed 元素(feed/channel)的屬性。

SyndicationFeed.add_root_elements(self, handler)

在根 Feed 元素(feed/channel)內新增元素的回呼。handler 是來自 Python 內建 SAX 函式庫的 XMLGenerator;您將呼叫它的方法來新增到處理中的 XML 文件。

SyndicationFeed.item_attributes(self, item)

傳回一個 dict,其中包含要新增到每個項目(item/entry)元素的屬性。參數 item 是一個字典,其中包含傳遞給 SyndicationFeed.add_item() 的所有資料。

SyndicationFeed.add_item_elements(self, handler, item)

在每個項目(item/entry)元素中新增元素的回呼。handleritem 如上所述。

警告

如果您覆寫這些方法中的任何一個,請務必呼叫父類別方法,因為它們會為每個 Feed 格式新增必要的元素。

例如,您可以開始實作類似這樣的 iTunes RSS Feed 產生器

class iTunesFeed(Rss201rev2Feed):
    def root_attributes(self):
        attrs = super().root_attributes()
        attrs["xmlns:itunes"] = "http://www.itunes.com/dtds/podcast-1.0.dtd"
        return attrs

    def add_root_elements(self, handler):
        super().add_root_elements(handler)
        handler.addQuickElement("itunes:explicit", "clean")

要完成自訂的 Feed 類別還有很多工作要做,但以上範例應可示範基本概念。

返回頂端