联合提要框架

Django 附带一个高级联合提要生成框架,用于创建 RSSAtom 提要。

要创建任何联合提要,您只需编写一个简短的 Python 类。您可以创建任意数量的提要。

Django 还附带一个低级提要生成 API。如果您希望在 Web 上下文之外或以其他低级方式生成提要,请使用此 API。

高级框架

概述

高级提要生成框架由 Feed 类提供。要创建提要,请编写一个 Feed 类,并在 URLconf 中指向它的实例。

Feed

A 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 连接到此提要,请在你的 URLconf 中放置 Feed 对象的一个实例。例如

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 }}
    • obj:由 get_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 类别是愚蠢的;这将违反 DRY 原则,并将数据与编程逻辑耦合。相反,联合框架允许你访问从 URLconf 传递的参数,以便提要可以根据提要 URL 中的信息输出项目。

可以通过以下 URL 访问警察巡逻区提要

  • /beats/613/rss/ – 返回巡逻区 613 的近期犯罪。
  • /beats/1424/rss/ – 返回巡逻区 1424 的近期犯罪。

这些可以与以下 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() 方法。在前面的示例中,它们是字符串类属性,但此示例说明它们可以是字符串方法。对于每个 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 类型有

附件

要指定外壳(例如用于创建播客提要的外壳),请使用 item_enclosures 钩子,或者如果每个项目只有一个外壳,则使用 item_enclosure_urlitem_enclosure_lengthitem_enclosure_mime_type 钩子。有关用法示例,请参阅下面的 ExampleFeed 类。

语言

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

网址

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

Atom 提要需要一个 <link rel="self"> 来定义提要的当前位置。联合框架将根据 SITE_ID 设置自动填充此信息,使用当前网站的域。

同时发布 Atom 和 RSS 提要

一些开发者喜欢同时提供 Atom RSS 版本的提要。为此,您可以创建 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 提要不提供提要级别的“说明”,但它们确实提供“副标题”。

如果您在 Feed 类中提供了 description,Django 不会 自动将其放入 subtitle 元素中,因为副标题和说明不一定相同。相反,您应该定义 subtitle 属性。

在上述示例中,我们将 Atom 提要的 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

    # 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 "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 = "[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 "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.

    # 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 框架使用底层框架来生成提要的 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 中,以便与 自定义提要生成器 一起使用。

除了 categories(它应该是一个字符串序列)之外,所有参数都应该是字符串。请注意,某些控制字符 不被允许 用于 XML 文档。如果你的内容包含其中一些内容,在生成提要时你可能会遇到 ValueError

SyndicationFeed.add_item()

使用给定参数向提要添加一个项目。

必需关键字参数是

  • title
  • link
  • description

可选关键字参数是

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

额外的关键字参数将存储用于 自定义提要生成器

如果给出,所有参数都应该是字符串,除了

SyndicationFeed.write()
将提要以给定的编码输出到 outfile,它是一个类似于文件的对象。
SyndicationFeed.writeString()
将提要作为字符串以给定的编码返回。

例如,要创建 Atom 1.0 提要并将其打印到标准输出

>>> 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>

自定义提要生成器

如果你需要生成自定义提要格式,你有几个选择。

如果提要格式完全自定义,你将需要对 SyndicationFeed 进行子类化,并完全替换 write()writeString() 方法。

但是,如果提要格式是 RSS 或 Atom 的衍生格式(即 GeoRSS、Apple 的 iTunes 播客格式 等),你会有更好的选择。这些类型的提要通常会向基础格式添加额外的元素和/或属性,并且有一组方法 SyndicationFeed 调用以获取这些额外属性。因此,你可以对适当的提要生成器类(Atom1FeedRss201rev2Feed)进行子类化并扩展这些回调。它们是

SyndicationFeed.root_attributes(self)
返回一个 dict,其中包含要添加到根提要元素(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 类,还有很多工作要做,但以上示例应该展示了基本思想。

返回顶部