聚合订阅源框架¶
Django 带有一个高级的聚合订阅源生成框架,用于创建 RSS 和 Atom 订阅源。
要创建任何聚合订阅源,您只需编写一个简短的 Python 类。您可以创建任意数量的订阅源。
Django 还附带了一个更低级的订阅源生成 API。如果您想在 Web 上下文之外或以其他更低级的方式生成订阅源,请使用此 API。
高级框架¶
概述¶
高级订阅源生成框架由 Feed
类提供。要创建订阅源,请编写一个 Feed
类,并在您的 URLconf 中指向它的实例。
Feed
类¶
一个 Feed
类是一个表示聚合订阅源的 Python 类。订阅源可以很简单(例如,“网站新闻”订阅源或显示博客最新条目的基本订阅源),也可以更复杂(例如,显示特定类别中所有博客条目的订阅源,其中类别是可变的)。
Feed
类是 django.contrib.syndication.views.Feed
的子类。它们可以存在于代码库中的任何位置。
一个简单的示例¶
这个简单的示例取自一个假设的警察巡逻新闻网站,描述了最新五条新闻的订阅源。
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
的子类。title
、link
和description
分别对应于标准 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_template
和description_template
属性指定。这些模板为每个项目呈现,并传递两个模板上下文变量。{{ obj }}
– 当前对象(您在items()
中返回的任何对象的其中一个)。{{ site }}
– 表示当前站点的django.contrib.sites.models.Site
对象。这对于{{ site.domain }}
或{{ site.name }}
很有用。如果您没有安装 Django 站点框架,则将其设置为RequestSite
对象。有关更多信息,请参阅 站点框架文档中的 RequestSite 部分。
请参阅下面的 复杂示例,其中使用了描述模板。
- 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。为每个警区创建一个单独的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()
方法。在前面的示例中,它们是字符串类属性,但此示例说明它们可以是字符串或方法。对于title
、link
和description
中的每一个,Django 遵循以下算法
首先,它尝试调用一个方法,并传递
obj
参数,其中obj
是get_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 类型为
django.utils.feedgenerator.Rss201rev2Feed
(RSS 2.01。默认值。)django.utils.feedgenerator.Atom1Feed
(Atom 1.0。)
附件¶
要指定附件(例如在创建播客 Feed 时使用的附件),请使用item_enclosures
钩子,或者,如果您每个项目只有一个附件,则可以使用item_enclosure_url
、item_enclosure_length
和item_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 生成器 使用。
所有参数(如果给出)都应为字符串,除了
pubdate
应为 Pythondatetime
对象。updateddate
应为 Pythondatetime
对象。enclosures
应为django.utils.feedgenerator.Enclosure
实例的列表。categories
应为字符串序列。
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 生成器类(Atom1Feed
或 Rss201rev2Feed
)并扩展这些回调。它们是
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
)元素添加元素。handler
和item
如上所述。
警告
如果您覆盖了任何这些方法,请务必调用超类方法,因为它们会添加每种 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 类,还有很多工作要做,但上面的示例应该说明了基本思想。