聚合订阅源框架

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() 都应该将项目的 URL 作为普通的 Python 字符串返回。与get_absolute_url()一样,item_link()的结果将直接包含在 URL 中,因此您有责任在方法本身内部执行所有必要的 URL 引用和转换为 ASCII。

一个复杂的例子

该框架还通过参数支持更复杂的 Feed。

例如,一个网站可以提供一个城市中每个警区的近期犯罪事件的 RSS Feed。为每个警区创建一个单独的Feed 类是很愚蠢的;这将违反DRY 原则,并将数据耦合到编程逻辑。相反,syndication 框架允许您访问从您的URLconf传递的参数,以便 Feed 可以根据 Feed URL 中的信息输出项目。

警区 Feed 可以通过以下 URL 访问

  • /beats/613/rss/ – 返回警区 613 的近期犯罪事件。

  • /beats/1424/rss/ – 返回警区 1424 的近期犯罪事件。

这些可以使用类似于以下的URLconf 行匹配

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

与视图类似,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 参数,其中objget_object() 返回的对象。

  • 如果失败,它尝试调用一个没有参数的方法。

  • 如果失败,它使用类属性。

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

我们正在使用模板来描述项目。它可以像这样简短

{{ obj.description }}

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

下面的ExampleFeed 类提供了关于Feed 类的方法和属性的完整文档。

指定 Feed 类型

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

要更改它,请向您的Feed 类添加一个feed_type 属性,如下所示

from django.utils.feedgenerator import Atom1Feed


class MyFeed(Feed):
    feed_type = Atom1Feed

请注意,您将feed_type 设置为类对象,而不是实例。

当前可用的 Feed 类型为

附件

要指定附件(例如在创建播客 Feed 时使用的附件),请使用item_enclosures 钩子,或者,如果您每个项目只有一个附件,则可以使用item_enclosure_urlitem_enclosure_lengthitem_enclosure_mime_type 钩子。有关用法示例,请参见下面的ExampleFeed 类。

语言

由 syndication 框架创建的 Feed 自动包含适当的<language> 标记(RSS 2.0)或xml:lang 属性(Atom)。默认情况下,这是django.utils.translation.get_language()。您可以通过设置language 类属性来更改它。

URL

link 方法/属性可以返回绝对路径(例如"/blog/")或具有完整限定域名和协议的 URL(例如"https://www.example.com/blog/")。如果link 未返回域名,则 syndication 框架将根据您的SITE_ID setting插入当前站点的域名。

Atom Feed 需要一个<link rel="self">,它定义了 Feed 的当前位置。syndication 框架会自动填充它,使用根据SITE_ID 设置的当前站点的域名。

同时发布 Atom 和 RSS Feed

一些开发者希望同时提供 Atom 和 RSS 版本的 Feed。为此,您可以创建您的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 属性。

在上面的示例中,我们将 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 = "[email protected]"  # 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 = "[email protected]"  # 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

  • 链接

  • 描述

还有一些其他的可选关键字

  • 语言

  • 作者邮箱

  • 作者姓名

  • 作者链接

  • 副标题

  • 类别

  • Feed URL

  • Feed 版权

  • Feed GUID

  • TTL

传递给 __init__ 的任何额外的关键字参数都将存储在 self.feed 中,供 自定义 Feed 生成器 使用。

所有参数都应为字符串,除了 categories,它应该是一个字符串序列。请注意,某些控制字符在 XML 文档中 不允许使用。如果您的内容包含其中一些字符,则在生成 Feed 时可能会遇到 ValueError

SyndicationFeed.add_item()

使用给定的参数向 Feed 添加一个条目。

必需的关键字参数为

  • title

  • 链接

  • 描述

可选的关键字参数为

  • 作者邮箱

  • 作者姓名

  • 作者链接

  • 发布日期

  • 评论

  • 唯一 ID

  • 附件

  • 类别

  • 条目版权

  • TTL

  • 更新日期

额外的关键字参数将被存储供 自定义 Feed 生成器 使用。

所有参数(如果给出)都应为字符串,除了

SyndicationFeed.write()

以给定的编码将 Feed 输出到 outfile,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 类,还有很多工作要做,但上面的示例应该说明了基本思想。

返回顶部