联合饲料框架

Django附带了一个高级别的联合提要生成框架,它使 RSSAtom 进食容易。

要创建任何联合提要,您所要做的就是编写一个简短的Python类。您可以创建任意数量的源。

Django还附带了一个生成API的低级提要。如果要在Web上下文之外或以其他较低级别的方式生成源,请使用此选项。

高层框架

概述

高级提要生成框架由 Feed 类。要创建提要,请编写 Feed 类并指向您的 URLconf .

Feed

A Feed 类是表示联合源的python类。提要可以是简单的(例如,“站点新闻”提要,或显示博客最新条目的基本提要)或更复杂的(例如,显示特定类别中所有博客条目的提要,其中类别是可变的)。

提要类子类 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连接到此源,请在 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> 元素。尽管这个例子返回 NewsItem 使用Django的对象 object-relational mapperitems() 不必返回模型实例。虽然使用django模型可以“免费”获得一些功能, items() 可以返回任何类型的对象。
  • 如果要创建Atom源而不是RSS源,请设置 subtitle 属性而不是 description 属性。见 Publishing Atom and RSS feeds in tandem 稍后,举个例子。

还有一件事要做。在RSS源中,每个 <item> 有一个 <title><link><description> . 我们需要告诉框架将哪些数据放入这些元素中。

  • 关于 <title><description> ,Django尝试调用方法 item_title()item_description()Feed 类。它们只传递一个参数, item ,这是对象本身。这些是可选的;默认情况下,对象的字符串表示用于这两者。

    如果要对标题或描述进行特殊格式设置, Django templates 可以改为使用。它们的路径可以用 title_templatedescription_template 上的属性 Feed 类。为每个项呈现模板,并传递两个模板上下文变量:

    a complex example 下面使用描述模板。

    Feed.get_context_data(**kwargs)

    如果需要提供超过前面提到的两个变量,还可以将附加信息传递给标题和描述模板。您可以提供 get_context_data 你的方法 Feed 子类。例如::

    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 }}}} .
    • obj :返回的对象 get_object() . 默认情况下,这不会暴露在模板中,以避免与 {{{{ obj }}}} (见上文),但您可以在实现 get_context_data() .
    • site :如上所述的当前站点。
    • request :当前请求。

    行为 get_context_data() 模仿的 generic views -你应该调用 super() 要从父类中检索上下文数据,请添加数据并返回修改过的字典。

  • 指定的内容 <link> ,您有两个选项。对于中的每个项目 items() ,Django第一次尝试调用 item_link() 方法在 Feed 类。以类似于标题和描述的方式,它被传递给单个参数, item . 如果该方法不存在,Django将尝试执行 get_absolute_url() 方法。两个 get_absolute_url()item_link() 应将该项的URL作为普通的python字符串返回。和一样 get_absolute_url() 的结果 item_link() 将直接包含在URL中,因此您负责在方法本身内进行所有必要的URL引用和转换为ASCII。

一个复杂的例子

框架还通过参数支持更复杂的提要。

例如,一个网站可以为一个城市中每一个被殴打的警察提供最近犯罪的RSS源。创建一个单独的 Feed 每打一次警察就得上课;这会违反 DRY principle 并将数据与编程逻辑耦合。相反,联合框架允许您访问从 URLconf 所以提要可以根据提要URL中的信息输出项目。

可以通过以下URL访问警察殴打源:

  • /beats/613/rss/ --返回Beat 613最近的犯罪记录。
  • /beats/1424/rss/ --返回Beat1424最近的犯罪记录。

这些可以与 URLconf 线如:

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

与视图类似,URL中的参数被传递到 get_object() 方法和请求对象。

以下是这些节拍特定源的代码:

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]

生成源的 <title><link><description> ,Django使用 title()link()description() 方法。在上一个示例中,它们是简单的字符串类属性,但是这个示例说明它们可以是字符串 or 方法。对于每一个 titlelinkdescription ,Django遵循此算法:

  • 首先,它尝试调用一个方法,传递 obj 论点,在哪里 obj 对象是否由返回 get_object() .
  • 失败的是,它试图调用一个没有参数的方法。
  • 否则,它将使用class属性。

还要注意 items() 同样遵循同样的算法——首先,它尝试 items(obj) 然后 items() 最后是一个 items 类属性(应该是列表)。

我们正在使用项目描述模板。它可以非常简单:

{{ obj.description }}

但是,您可以根据需要自由添加格式。

这个 ExampleFeed 下面的类提供了关于 Feed 类。

指定馈送类型

默认情况下,此框架中生成的提要使用RSS 2.0。

要更改,请添加 feed_type attribute to your Feed 课堂,就像这样:

from django.utils.feedgenerator import Atom1Feed

class MyFeed(Feed):
    feed_type = Atom1Feed

注意你设置了 feed_type 类对象,而不是实例。

当前可用的源类型为:

围栏

要指定附件(如用于创建播客源的附件),请使用 item_enclosures 或者,如果每个项目只有一个外壳, item_enclosure_urlitem_enclosure_lengthitem_enclosure_mime_type 钩子。见 ExampleFeed 下面的类用于示例。

语言

联合框架创建的源自动包括 <language> 标签(RSS 2.0)或 xml:lang 属性(Atom)。这是直接从你的 LANGUAGE_CODE 设置。

URLs

这个 link 方法/属性可以返回绝对路径(例如 "/blog/" )或具有完全限定的域和协议的URL(例如 "https://www.example.com/blog/" )如果 link 不返回域,根据您的 SITE_ID setting .

Atom源需要 <link rel="self"> 它定义提要的当前位置。联合框架自动填充此内容,根据 SITE_ID 设置。

同时发布Atom和RSS源

一些开发人员喜欢同时提供两个Atom and 他们订阅源的RSS版本。使用django很容易:只需创建 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源使用 description 而Atom提要使用 subtitle . 这是因为Atom提要不提供提要级别的“描述”,但是它们 do 提供“副标题”。

如果你提供 description 在你 Feed 班, Django 威尔 not 自动将其放入 subtitle 元素,因为副标题和描述不一定是相同的。相反,您应该定义 subtitle 属性。

在上面的示例中,我们只需设置原子馈送的 subtitle 到RSS源 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

    # 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 "http://" 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 "http://" 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.

低级框架

在幕后,高级RSS框架使用较低级别的框架来生成提要的XML。此框架位于单个模块中: django/utils/feedgenerator.py .

您可以自己使用这个框架来生成较低级别的提要。您还可以创建自定义的提要生成器子类,用于 feed_type Feed 选择权。

SyndicationFeed

这个 feedgenerator 模块包含一个基类:

以及几个子类:

这三个类中的每一个都知道如何将某种类型的提要呈现为XML。它们共享此接口:

SyndicationFeed.__init__()

使用给定的元数据字典初始化源,该字典适用于整个源。必需的关键字参数是:

  • title
  • link
  • description

还有许多其他可选关键字:

  • language
  • author_email
  • author_name
  • author_link
  • subtitle
  • categories
  • feed_url
  • feed_copyright
  • feed_guid
  • ttl

传递给的任何其他关键字参数 __init__ 将存储在 self.feed 供使用 custom feed generators .

所有参数都应为字符串,除非 categories ,它应该是一个字符串序列。注意一些控制字符 not allowed 在XML文档中。如果您的内容中有一些内容,您可能会遇到 ValueError 生产饲料时。

SyndicationFeed.add_item()

使用给定参数向提要中添加项。

必需的关键字参数是:

  • title
  • link
  • description

可选关键字参数包括:

  • author_email
  • author_name
  • author_link
  • pubdate
  • comments
  • unique_id
  • enclosures
  • categories
  • item_copyright
  • ttl
  • updateddate

将为存储额外的关键字参数 custom feed generators .

所有参数(如果给定)都应该是字符串,除了:

SyndicationFeed.write()
将给定编码中的提要输出到outfile,这是一个类似文件的对象。
SyndicationFeed.writeString()
以给定编码的字符串形式返回源。

例如,要创建Atom 1.0源并将其打印到标准输出,请执行以下操作:

>>> from django.utils import feedgenerator
>>> from datetime import datetime
>>> f = feedgenerator.Atom1Feed(
...     title="My Weblog",
...     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>

自定义源生成器

如果您需要生成自定义的提要格式,您有几个选项。

如果提要格式完全是自定义的,那么您需要子类 SyndicationFeed 完全取代 write()writeString() 方法。

但是,如果提要格式是RSS或Atom(即 GeoRSS, 苹果公司 iTunes podcast format 等等),你有更好的选择。这些类型的提要通常向基础格式添加额外的元素和/或属性,并且有一组方法 SyndicationFeed 调用以获取这些额外属性。因此,您可以将适当的提要生成器类划分为子类。 (Atom1FeedRss201rev2Feed )并延长这些回调。他们是:

SyndicationFeed.root_attributes(self)
返回A dict of attributes to add to the root feed element (feed/channel
SyndicationFeed.add_root_elements(self, handler)
回调以在根馈送元素中添加元素 (feed /‘频道’)。 handler 是一个 XMLGenerator 从Python的内置SAX库中,您将调用它的方法来添加到正在处理的XML文档中。
SyndicationFeed.item_attributes(self, item)
返回A dict of attributes to add to each item (item/entry )元素。争论, item ,是传递给的所有数据的字典 SyndicationFeed.add_item() .
SyndicationFeed.add_item_elements(self, handler, item)
回调以向每个项添加元素 (item /`` entry``)元素。 handleritem 如上。

警告

如果重写这些方法中的任何一个,请确保调用超类方法,因为它们为每个提要格式添加了必需的元素。

例如,您可以开始实现类似这样的iTunes RSS提要生成器:

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类还有很多工作要做,但是上面的示例应该演示基本的思想。