目录
联合提要框架
Django 带有一个高级联合提要生成框架,用于创建 RSS 和 Atom 提要。
要创建任何联合提要,您所要做的就是编写一个简短的 Python 类。 您可以根据需要创建任意数量的提要。
Django 还带有一个较低级别的提要生成 API。 如果您想在 Web 上下文之外或以其他较低级别的方式生成提要,请使用此选项。
高级框架
Feed 类
Feed 类是表示联合提要的 Python 类。 提要可以很简单(例如,“站点新闻”提要,或显示博客最新条目的基本提要)或更复杂(例如,显示特定类别中所有博客条目的提要,其中类别是可变的)。
提要类子类 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()
都应该以普通 Python 字符串的形式返回项目的 URL。 与get_absolute_url()
一样,item_link()
的结果将直接包含在 URL 中,因此您负责在方法本身内部进行所有必要的 URL 引用和转换为 ASCII。
一个复杂的例子
该框架还通过参数支持更复杂的提要。
例如,一个网站可以为一个城市的每一个警察殴打提供最近犯罪的 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()
方法。 在前面的示例中,它们是字符串类属性,但此示例说明它们可以是字符串 或 方法。 对于 title
、link
和 description
中的每一个,Django 遵循以下算法:
- 首先,它尝试调用一个方法,传递
obj
参数,其中obj
是get_object()
返回的对象。 - 如果失败,它会尝试调用一个没有参数的方法。
- 否则,它将使用 class 属性。
还要注意 items()
也遵循相同的算法——首先,它尝试 items(obj)
,然后是 items()
,最后是 items
类属性(应该是一个列表)。
我们正在为项目描述使用模板。 它可以像这样最小:
{{ obj.description }}
但是,您可以根据需要自由添加格式。
下面的 ExampleFeed
类给出了关于 Feed 类的方法和属性的完整文档。
指定提要类型
默认情况下,此框架中生成的提要使用 RSS 2.0。
要更改它,请将 feed_type
属性添加到您的 Feed 类,如下所示:
from django.utils.feedgenerator import Atom1Feed
class MyFeed(Feed):
feed_type = Atom1Feed
请注意,您将 feed_type
设置为类对象,而不是实例。
当前可用的提要类型有:
- django.utils.feedgenerator.Rss201rev2Feed (RSS 2.01. 默认。)
- django.utils.feedgenerator.RssUserland091Feed (RSS 0.91。)
- django.utils.feedgenerator.Atom1Feed (Atom 1.0.)
外壳
要指定附件,例如用于创建播客提要的附件,请使用 item_enclosures
挂钩,或者,如果每个项目只有一个附件,则使用 item_enclosure_url
、item_enclosure_length
, 和 item_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/%22
)。 如果link
不返回域,联合框架将插入当前站点的域,根据您的 :setting:`SITE_ID 设置 ` .
Atom 提要需要一个 <link rel="self">
来定义提要的当前位置。 联合框架根据 :setting:`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 将 not 自动将其放入 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 = '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.
# 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
在 3.2 版更改:通过 item_comments
挂钩添加了对每个提要项目的评论 URL 的支持。
低级框架
在幕后,高级 RSS 框架使用低级框架来生成提要的 XML。 该框架存在于单个模块中::source:`django/utils/feedgenerator.py`。
您可以自己使用此框架来生成较低级别的提要。 您还可以创建自定义提要生成器子类以与 feed_type
Feed
选项一起使用。
SyndicationFeed 类
feedgenerator 模块包含一个基类:
和几个子类:
django.utils.feedgenerator.RssUserland091Feed
django.utils.feedgenerator.Rss201rev2Feed
django.utils.feedgenerator.Atom1Feed
这三个类中的每一个都知道如何将某种类型的提要呈现为 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
将为 自定义提要生成器 存储额外的关键字参数。
所有参数,如果给定,都应该是字符串,除了:
pubdate
应该是一个 Pythondatetime
对象。updateddate
应该是一个 Pythondatetime
对象。enclosures
应该是 django.utils.feedgenerator.Enclosure 实例的列表。categories
应该是一个字符串序列。
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 播客格式等),你有更好的选择。 这些类型的提要通常会向底层格式添加额外的元素和/或属性,并且有一组 SyndicationFeed
调用的方法来获取这些额外的属性。 因此,您可以子类化适当的提要生成器类(Atom1Feed
或 Rss201rev2Feed
)并扩展这些回调。 他们是:
SyndicationFeed.root_attributes(self)
- 返回
dict
属性以添加到根提要元素 (feed
/channel
)。 SyndicationFeed.add_root_elements(self, handler)
- 回调以在根提要元素 (
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
同上。
警告
如果您覆盖这些方法中的任何一个,请务必调用超类方法,因为它们为每种提要格式添加了所需的元素。
例如,您可能会开始实现一个 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')
对于一个完整的自定义提要类,还有很多工作要做,但上面的例子应该展示了基本思想。