{% raw %}

Feed聚合框架

Django带有一个高聚合的框架让创造RSSAtom更容易。

创建聚合feed,你要做的仅仅是写一个简短的Python类。你想要创造多少,就能创造多少feeds。

Django 也带有一个低等级的生成feed的API。如果你想要生成一个外部的Web内容或者其他普通的方式,你可以使用它。

高等级的框架

概述

高等级的feed聚合框架由Feed类提供。新建一个feed,写一个Feed类,然后指向你的URLconf.

Feed 类

一个 Feed类就是一个提供聚合种子的Python类。一个简单的种子(例如新闻的信息种子,或者只展示博客最新消息)更多功能的种子(例如展示博客中允许展示的特定类别的条目)。

Feed类继承自django.contrib.syndication.views.Feed。它们可以在你代码中的任意一处。

Feed类需要是你URLconf中的实例。

一个简单的示例

这个简单的示例,演示了某站点的最近五条新闻的记录:

  1. from django.contrib.syndication.views import Feed
  2. from django.core.urlresolvers import reverse
  3. from policebeat.models import NewsItem
  4. class LatestEntriesFeed(Feed):
  5. title = "Police beat site news"
  6. link = "/sitenews/"
  7. description = "Updates on changes and additions to police beat central."
  8. def items(self):
  9. return NewsItem.objects.order_by('-pub_date')[:5]
  10. def item_title(self, item):
  11. return item.title
  12. def item_description(self, item):
  13. return item.description
  14. # item_link is only needed if NewsItem has no get_absolute_url method.
  15. def item_link(self, item):
  16. return reverse('news-item', args=[item.pk])

配置一个URL到这个feed,在URLconf中配置一个入口。例如:

  1. from django.conf.urls import url
  2. from myproject.feeds import LatestEntriesFeed
  3. urlpatterns = [
  4. # ...
  5. url(r'^latest/feed/$', LatestEntriesFeed()),
  6. # ...
  7. ]

注意:

  • Feed类继承于django.contrib.syndication.views.Feed.
  • title, linkdescription 分别对应 RSS的 <title>, <link><description> .
  • items()就是一个返回包含feed <item>对象列表的方法.当然,这个例子返回 NewsItem对象是使用 Django的 object-relational mapper, items() 没有返回模型的实例。当然,你可以从Django模型中很容易的获取一些数据,items()可以返回任何你想要的对象。
  • 如果你要创建一个Atom feed,而不是RSS feed,你需要使用subtitle属性替代description。查看Publishing Atom and RSS feeds in tandem里面的例子。

还有一件事没做。在一个 RSS feed中, 每一个 <item> 都有一个<title>, <link><description>. 我们需要告诉框架那些数据放进这些对象中。

  • <title><description>的内容中,Django尝试着在Feed类中召集item_title()item_description()方法。他们会传入一个自己内部的单独的参数 item。这些都是可选的; 默认的是,unicode表示的对象都被使用了
    如果你想要做一些特殊的格式化title或者description,Django templates可以帮助你。他们的路径会被Feed类中的title_templatedescription_template 参数做特殊处理。会通过模板内容的两个变量来返回每一条记录到模板中:

a complex example 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”

  1. def items(self):
  2. return Article.objects.order_by('-pub_date')[:5]
  3. def get_context_data(self, **kwargs):
  4. context = super(ArticlesFeed, self).get_context_data(**kwargs)
  5. context['foo'] = 'bar'
  6. return context

Something about {{ foo }}: {{ obj.description }}

  1. `items()`
  2. - `item`:当前项目。出于向后兼容性原因,此上下文变量的名称为`{% obj %}`
  3. - `obj``get_object()`返回的对象。默认情况下,这不会暴露给模板,以避免与`{% obj %}` ,但您可以在实现`get_context_data()`时使用它。
  4. - `site`:如上所述的当前网站。
  5. - `request`:当前请求。
  6. `get_context_data()`[_generic views_](_topics_class-based-views_generic-display.html#adding-extra-context)`super()`
  7. -
  8. 要指定`<link>`的内容,您有两个选项。对于`items()`中的每个项目,Django首先尝试调用[`Feed`](486c9fc7a88c3b5c025c2cd87c3cd225)类上的`item_link()`方法。以类似于标题和描述的方式,它传递单个参数`item`。如果该方法不存在,Django尝试对该对象执行`get_absolute_url()`方法。`get_absolute_url()``item_link()`应将项目的网址作为普通的Python字符串返回。与`get_absolute_url()`一样,`item_link()`的结果将直接包含在URL中,因此您负责对所有必要的URL进行引用并将其转换为ASCII方法本身。
  9. <a name="a64ed0f0"></a>
  10. ### 一个复杂的例子
  11. 该框架还通过参数支持更复杂的feed
  12. 例如,网站可以为城市中的每个警察节拍提供最近的犯罪的RSS源。为每个警察节拍创建一个单独的[`Feed`](486c9fc7a88c3b5c025c2cd87c3cd225)课;这将违反[_DRY principle_](_misc_design-philosophies.html#dry)并且将数据耦合到编程逻辑。相反,联合框架可让您访问从[_URLconf_](_topics_http_urls.html)传递的参数,以便Feed可以根据Feed的网址中的信息输出项目。
  13. 警察打击饲料可以通过这样的URL访问:
  14. - `/beats/613/rss/` - 返回613的最近犯罪。
  15. - `/beats/1424/rss/` - 返回1424年最近的犯罪。
  16. 这些可以与[_URLconf_](_topics_http_urls.html)行匹配,例如:

url(r’^beats/(?P[0-9]+)/rss/$’, BeatFeed()),

  1. 与视图类似,URL中的参数与请求对象一起传递到`get_object()`方法。
  2. 以下是这些特定于节拍的Feed的代码:

from django.contrib.syndication.views import FeedDoesNotExist from django.shortcuts import get_object_or_404

class BeatFeed(Feed): description_template = ‘feeds/beat_description.html’

  1. def get_object(self, request, beat_id):
  2. return get_object_or_404(Beat, pk=beat_id)
  3. def title(self, obj):
  4. return "Police beat central: Crimes for beat %s" % obj.beat
  5. def link(self, obj):
  6. return obj.get_absolute_url()
  7. def description(self, obj):
  8. return "Crimes recently reported in police beat %s" % obj.beat
  9. def items(self, obj):
  10. return Crime.objects.filter(beat=obj).order_by('-crime_date')[:30]
  1. To generate the feeds `&lt;title&gt;`, `&lt;link&gt;` and `&lt;description&gt;`, Django uses the `title()`, `link()` and `description()` methods. 在前面的示例中,它们是简单的字符串类属性,但是本示例说明它们可以是字符串__方法。对于`title``link``description`中的每一个,Django都遵循此算法:
  2. - 首先,它尝试调用传递`obj`参数的方法,其中`obj`是由`get_object()`返回的对象。
  3. - 如果没有,它试图调用没有参数的方法。
  4. - 如果没有,它使用类属性。
  5. 还要注意,`items()`也遵循相同的算法 - 首先,它尝试`items(obj)`,然后`items()` `items`类属性(它应该是一个列表)。
  6. 我们正在使用模板作为项目描述。它可以很简单:

{{ obj.description }}

  1. 但是,您可以根据需要自由添加格式。
  2. 下面的`ExampleFeed`类提供了有关[`Feed`](486c9fc7a88c3b5c025c2cd87c3cd225)类的方法和属性的完整文档。
  3. <a name="4eb8e2be"></a>
  4. ### 指定Feed的类型
  5. 默认情况下,此框架中生成的Feed使用RSS 2.0
  6. 要更改此属性,请向您的[`Feed`](486c9fc7a88c3b5c025c2cd87c3cd225)类添加`feed_type`属性,如下所示:

from django.utils.feedgenerator import Atom1Feed

class MyFeed(Feed): feed_type = Atom1Feed

  1. 请注意,您将`feed_type`设置为类对象,而不是实例。
  2. 目前可用的Feed类型有:
  3. - [`django.utils.feedgenerator.Rss201rev2Feed`](703ccc64475acd54a8019d9cdb44e9c5)(RSS 2.01。默认。)
  4. - [`django.utils.feedgenerator.RssUserland091Feed`](7d4c5e298fd0c76cec8e5156076e7ce9)(RSS 0.91.)
  5. - [`django.utils.feedgenerator.Atom1Feed`](4af197e6c5697ca3074305565d6513c4)(Atom 1.0.)
  6. <a name="c9a6ee90"></a>
  7. ### 附件
  8. 要指定机柜(例如用于创建Podcast Feed的机柜),请使用`item_enclosure_url``item_enclosure_length``item_enclosure_mime_type`挂钩。有关用法示例,请参见下面的`ExampleFeed`类。
  9. <a name="295bb704"></a>
  10. ### 语言
  11. 由联合框架创建的Feed会自动包含适当的`&lt;language&gt;`标记(RSS 2.0)或`xml:lang`属性(Atom)。这直接来自您的[`LANGUAGE_CODE`]()设置。
  12. <a name="b3b91f77"></a>
  13. ### 网址
  14. `link`方法/属性可以返回绝对路径(例如`"/blog/"`)或具有完全限定域和协议的URL(例如`"http://www.example.com/blog/"`)。如果`link`未返回域,则整合框架将根据您的[`SITE_ID setting`]()。
  15. Atom Feed需要定义Feed的当前位置的`&lt; link rel =“self”&gt;`
  16. <a name="fd8feafc"></a>
  17. ### 串联发布Atom和RSS Feed
  18. 有些开发人员喜欢提供Atom __ RSS版本的Feed。使用Django很容易:只需创建[`Feed`](486c9fc7a88c3b5c025c2cd87c3cd225)类的子类,并将`feed_type`设置为不同的类型即可。然后更新您的URLconf以添加额外的版本。
  19. 这里有一个完整的例子:

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

  1. def items(self):
  2. return NewsItem.objects.order_by('-pub_date')[:5]

class AtomSiteNewsFeed(RssSiteNewsFeed): feed_type = Atom1Feed subtitle = RssSiteNewsFeed.description

  1. 注意
  2. 在此示例中,RSS提要使用`description`,而Atom提要使用`subtitle`。这是因为Atom Feed不提供Feed级“说明”,但他们提供“字幕”。
  3. 如果您在[`Feed`](486c9fc7a88c3b5c025c2cd87c3cd225)类中提供`description`Django_不会_自动将其放入`subtitle`字幕和描述不一定是同一件事。而应定义`subtitle`属性。
  4. 在上面的示例中,我们只需将Atom Feed`subtitle`设置为RSS Feed`description`,因为它已经很短。
  5. 和附带的URLconf

from django.conf.urls import url from myproject.feeds import RssSiteNewsFeed, AtomSiteNewsFeed

urlpatterns = [

  1. # ...
  2. url(r'^sitenews/rss/$', RssSiteNewsFeed()),
  3. url(r'^sitenews/atom/$', AtomSiteNewsFeed()),
  4. # ...

]

  1. <a name="9d7ebafc"></a>
  2. ### Feed类引用
  3. _class_ `views.``Feed`
  4. 此示例说明[`Feed`](486c9fc7a88c3b5c025c2cd87c3cd225)类的所有可能的属性和方法:

from django.contrib.syndication.views import Feed from django.utils import feedgenerator

class ExampleFeed(Feed):

  1. # FEED TYPE -- Optional. This should be a class that subclasses
  2. # django.utils.feedgenerator.SyndicationFeed. This designates
  3. # which type of feed this should be: RSS 2.0, Atom 1.0, etc. If
  4. # you don't specify feed_type, your feed will be RSS 2.0\. This
  5. # should be a class, not an instance of the class.
  6. feed_type = feedgenerator.Rss201rev2Feed
  7. # TEMPLATE NAMES -- Optional. These should be strings
  8. # representing names of Django templates that the system should
  9. # use in rendering the title and description of your feed items.
  10. # Both are optional. If a template is not specified, the
  11. # item_title() or item_description() methods are used instead.
  12. title_template = None
  13. description_template = None
  14. # TITLE -- One of the following three is required. The framework
  15. # looks for them in this order.
  16. def title(self, obj):
  17. """

Takes the object returned by get_object() and returns the feed’s title as a normal Python string. “””

  1. def title(self):
  2. """

Returns the feed’s title as a normal Python string. “””

  1. title = 'foo' # Hard-coded title.
  2. # LINK -- One of the following three is required. The framework
  3. # looks for them in this order.
  4. def link(self, obj):
  5. """

Takes the object returned by get_object() and returns the URL

of the HTML version of the feed as a normal Python string.

“””

  1. def link(self):
  2. """

Returns the URL of the HTML version of the feed as a normal Python string. “””

  1. link = '/blog/' # Hard-coded URL.
  2. # FEED_URL -- One of the following three is optional. The framework
  3. # looks for them in this order.
  4. def feed_url(self, obj):
  5. """

Takes the object returned by get_object() and returns the feed’s

own URL as a normal Python string.

“””

  1. def feed_url(self):
  2. """

Returns the feed’s own URL as a normal Python string. “””

  1. feed_url = '/blog/rss/' # Hard-coded URL.
  2. # GUID -- One of the following three is optional. The framework looks
  3. # for them in this order. This property is only used for Atom feeds
  4. # (where it is the feed-level ID element). If not provided, the feed
  5. # link is used as the ID.
  6. def feed_guid(self, obj):
  7. """

Takes the object returned by get_object() and returns the globally unique ID for the feed as a normal Python string. “””

  1. def feed_guid(self):
  2. """

Returns the feed’s globally unique ID as a normal Python string. “””

  1. feed_guid = '/foo/bar/1234' # Hard-coded guid.
  2. # DESCRIPTION -- One of the following three is required. The framework
  3. # looks for them in this order.
  4. def description(self, obj):
  5. """

Takes the object returned by get_object() and returns the feed’s description as a normal Python string. “””

  1. def description(self):
  2. """

Returns the feed’s description as a normal Python string. “””

  1. description = 'Foo bar baz.' # Hard-coded description.
  2. # AUTHOR NAME --One of the following three is optional. The framework
  3. # looks for them in this order.
  4. def author_name(self, obj):
  5. """

Takes the object returned by get_object() and returns the feed’s author’s name as a normal Python string. “””

  1. def author_name(self):
  2. """

Returns the feed’s author’s name as a normal Python string. “””

  1. author_name = 'Sally Smith' # Hard-coded author name.
  2. # AUTHOR EMAIL --One of the following three is optional. The framework
  3. # looks for them in this order.
  4. def author_email(self, obj):
  5. """

Takes the object returned by get_object() and returns the feed’s author’s email as a normal Python string. “””

  1. def author_email(self):
  2. """

Returns the feed’s author’s email as a normal Python string. “””

  1. author_email = 'test@example.com' # Hard-coded author email.
  2. # AUTHOR LINK --One of the following three is optional. The framework
  3. # looks for them in this order. In each case, the URL should include
  4. # the "http://" and domain name.
  5. def author_link(self, obj):
  6. """

Takes the object returned by get_object() and returns the feed’s author’s URL as a normal Python string. “””

  1. def author_link(self):
  2. """

Returns the feed’s author’s URL as a normal Python string. “””

  1. author_link = 'http://www.example.com/' # Hard-coded author URL.
  2. # CATEGORIES -- One of the following three is optional. The framework
  3. # looks for them in this order. In each case, the method/attribute
  4. # should return an iterable object that returns strings.
  5. def categories(self, obj):
  6. """

Takes the object returned by get_object() and returns the feed’s categories as iterable over strings. “””

  1. def categories(self):
  2. """

Returns the feed’s categories as iterable over strings. “””

  1. categories = ("python", "django") # Hard-coded list of categories.
  2. # COPYRIGHT NOTICE -- One of the following three is optional. The
  3. # framework looks for them in this order.
  4. def feed_copyright(self, obj):
  5. """

Takes the object returned by get_object() and returns the feed’s copyright notice as a normal Python string. “””

  1. def feed_copyright(self):
  2. """

Returns the feed’s copyright notice as a normal Python string. “””

  1. feed_copyright = 'Copyright (c) 2007, Sally Smith' # Hard-coded copyright notice.
  2. # TTL -- One of the following three is optional. The framework looks
  3. # for them in this order. Ignored for Atom feeds.
  4. def ttl(self, obj):
  5. """

Takes the object returned by get_object() and returns the feed’s TTL (Time To Live) as a normal Python string. “””

  1. def ttl(self):
  2. """

Returns the feed’s TTL as a normal Python string. “””

  1. ttl = 600 # Hard-coded Time To Live.
  2. # ITEMS -- One of the following three is required. The framework looks
  3. # for them in this order.
  4. def items(self, obj):
  5. """

Takes the object returned by get_object() and returns a list of items to publish in this feed. “””

  1. def items(self):
  2. """

Returns a list of items to publish in this feed. “””

  1. items = ('Item 1', 'Item 2') # Hard-coded items.
  2. # GET_OBJECT -- This is required for feeds that publish different data
  3. # for different URL parameters. (See "A complex example" above.)
  4. def get_object(self, request, *args, **kwargs):
  5. """

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. “””

  1. # ITEM TITLE AND DESCRIPTION -- If title_template or
  2. # description_template are not defined, these are used instead. Both are
  3. # optional, by default they will use the unicode representation of the
  4. # item.
  5. def item_title(self, item):
  6. """

Takes an item, as returned by items(), and returns the item’s title as a normal Python string. “””

  1. def item_title(self):
  2. """

Returns the title for every item in the feed. “””

  1. item_title = 'Breaking News: Nothing Happening' # Hard-coded title.
  2. def item_description(self, item):
  3. """

Takes an item, as returned by items(), and returns the item’s description as a normal Python string. “””

  1. def item_description(self):
  2. """

Returns the description for every item in the feed. “””

  1. item_description = 'A description of the item.' # Hard-coded description.
  2. def get_context_data(self, **kwargs):
  3. """

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. “””

  1. # ITEM LINK -- One of these three is required. The framework looks for
  2. # them in this order.
  3. # First, the framework tries the two methods below, in
  4. # order. Failing that, it falls back to the get_absolute_url()
  5. # method on each item returned by items().
  6. def item_link(self, item):
  7. """

Takes an item, as returned by items(), and returns the item’s URL. “””

  1. def item_link(self):
  2. """

Returns the URL for every item in the feed. “””

  1. # ITEM_GUID -- The following method is optional. If not provided, the
  2. # item's link is used by default.
  3. def item_guid(self, obj):
  4. """

Takes an item, as return by items(), and returns the item’s ID. “””

  1. # ITEM_GUID_IS_PERMALINK -- The following method is optional. If
  2. # provided, it sets the 'isPermaLink' attribute of an item's
  3. # GUID element. This method is used only when 'item_guid' is
  4. # specified.
  5. def item_guid_is_permalink(self, obj):
  6. """

Takes an item, as returned by items(), and returns a boolean. “””

  1. item_guid_is_permalink = False # Hard coded value
  2. # ITEM AUTHOR NAME -- One of the following three is optional. The
  3. # framework looks for them in this order.
  4. def item_author_name(self, item):
  5. """

Takes an item, as returned by items(), and returns the item’s author’s name as a normal Python string. “””

  1. def item_author_name(self):
  2. """

Returns the author name for every item in the feed. “””

  1. item_author_name = 'Sally Smith' # Hard-coded author name.
  2. # ITEM AUTHOR EMAIL --One of the following three is optional. The
  3. # framework looks for them in this order.
  4. #
  5. # If you specify this, you must specify item_author_name.
  6. def item_author_email(self, obj):
  7. """

Takes an item, as returned by items(), and returns the item’s author’s email as a normal Python string. “””

  1. def item_author_email(self):
  2. """

Returns the author email for every item in the feed. “””

  1. item_author_email = 'test@example.com' # Hard-coded author email.
  2. # ITEM AUTHOR LINK -- One of the following three is optional. The
  3. # framework looks for them in this order. In each case, the URL should
  4. # include the "http://" and domain name.
  5. #
  6. # If you specify this, you must specify item_author_name.
  7. def item_author_link(self, obj):
  8. """

Takes an item, as returned by items(), and returns the item’s author’s URL as a normal Python string. “””

  1. def item_author_link(self):
  2. """

Returns the author URL for every item in the feed. “””

  1. item_author_link = 'http://www.example.com/' # Hard-coded author URL.
  2. # ITEM ENCLOSURE URL -- One of these three is required if you're
  3. # publishing enclosures. The framework looks for them in this order.
  4. def item_enclosure_url(self, item):
  5. """

Takes an item, as returned by items(), and returns the item’s enclosure URL. “””

  1. def item_enclosure_url(self):
  2. """

Returns the enclosure URL for every item in the feed. “””

  1. item_enclosure_url = "/foo/bar.mp3" # Hard-coded enclosure link.
  2. # ITEM ENCLOSURE LENGTH -- One of these three is required if you're
  3. # publishing enclosures. The framework looks for them in this order.
  4. # In each case, the returned value should be either an integer, or a
  5. # string representation of the integer, in bytes.
  6. def item_enclosure_length(self, item):
  7. """

Takes an item, as returned by items(), and returns the item’s enclosure length. “””

  1. def item_enclosure_length(self):
  2. """

Returns the enclosure length for every item in the feed. “””

  1. item_enclosure_length = 32000 # Hard-coded enclosure length.
  2. # ITEM ENCLOSURE MIME TYPE -- One of these three is required if you're
  3. # publishing enclosures. The framework looks for them in this order.
  4. def item_enclosure_mime_type(self, item):
  5. """

Takes an item, as returned by items(), and returns the item’s enclosure MIME type. “””

  1. def item_enclosure_mime_type(self):
  2. """

Returns the enclosure MIME type for every item in the feed. “””

  1. item_enclosure_mime_type = "audio/mpeg" # Hard-coded enclosure MIME type.
  2. # ITEM PUBDATE -- It's optional to use one of these three. This is a
  3. # hook that specifies how to get the pubdate for a given item.
  4. # In each case, the method/attribute should return a Python
  5. # datetime.datetime object.
  6. def item_pubdate(self, item):
  7. """

Takes an item, as returned by items(), and returns the item’s pubdate. “””

  1. def item_pubdate(self):
  2. """

Returns the pubdate for every item in the feed. “””

  1. item_pubdate = datetime.datetime(2005, 5, 3) # Hard-coded pubdate.
  2. # ITEM UPDATED -- It's optional to use one of these three. This is a
  3. # hook that specifies how to get the updateddate for a given item.
  4. # In each case, the method/attribute should return a Python
  5. # datetime.datetime object.
  6. def item_updateddate(self, item):
  7. """

Takes an item, as returned by items(), and returns the item’s updateddate. “””

  1. def item_updateddate(self):
  2. """

Returns the updateddated for every item in the feed. “””

  1. item_updateddate = datetime.datetime(2005, 5, 3) # Hard-coded updateddate.
  2. # ITEM CATEGORIES -- It's optional to use one of these three. This is
  3. # a hook that specifies how to get the list of categories for a given
  4. # item. In each case, the method/attribute should return an iterable
  5. # object that returns strings.
  6. def item_categories(self, item):
  7. """

Takes an item, as returned by items(), and returns the item’s categories. “””

  1. def item_categories(self):
  2. """

Returns the categories for every item in the feed. “””

  1. item_categories = ("python", "django") # Hard-coded categories.
  2. # ITEM COPYRIGHT NOTICE (only applicable to Atom feeds) -- One of the
  3. # following three is optional. The framework looks for them in this
  4. # order.
  5. def item_copyright(self, obj):
  6. """

Takes an item, as returned by items(), and returns the item’s copyright notice as a normal Python string. “””

  1. def item_copyright(self):
  2. """

Returns the copyright notice for every item in the feed. “””

  1. item_copyright = 'Copyright (c) 2007, Sally Smith' # Hard-coded copyright notice.
  1. <a name="9dcff8e8"></a>
  2. ## 低级框架
  3. 在后台,高级RSS框架使用较低级别的框架来生成订阅源的XML。此框架存在于单个模块中:[django / utils / feedgenerator.py](https://github.com/django/django/blob/master/django/utils/feedgenerator.py)。
  4. 您自己使用此框架,用于生成较低级别的Feed。您还可以创建自定义Feed生成器子类,以与`feed_type` `Feed`选项一起使用。
  5. <a name="98904659"></a>
  6. ### 联合供稿 classes
  7. [`feedgenerator`](5de86f2f06a3b35278ced82c525d9226)模块包含基类:
  8. - [django.utils.feedgenerator.SyndicationFeed](205d1ae84380c366b45853120b596631)
  9. 和几个子类:
  10. - [django.utils.feedgenerator.RssUserland091Feed](7d4c5e298fd0c76cec8e5156076e7ce9)
  11. - [django.utils.feedgenerator.Rss201rev2Feed](703ccc64475acd54a8019d9cdb44e9c5)
  12. - [django.utils.feedgenerator.Atom1Feed](4af197e6c5697ca3074305565d6513c4)
  13. 这三个类中的每一个都知道如何将某种类型的feed呈现为XML。他们共享这个接口:
  14. [`SyndicationFeed.__init__()`](a0a8daa392ea13a6545cef1c24f4fd8c)
  15. 使用给定的元数据字典初始化Feed,该元数据字典应用于整个Feed。必需的关键字参数为:
  16. - `title`
  17. - `link`
  18. - `description`
  19. 还有一堆其他可选关键字:
  20. - `language`
  21. - `author_email`
  22. - `author_name`
  23. - `author_link`
  24. - `subtitle`
  25. - `categories`
  26. - `feed_url`
  27. - `feed_copyright`
  28. - `feed_guid`
  29. - `ttl`
  30. 您传递给`__init__`的任何其他关键字参数将存储在`self.feed`中以与[自定义Feed生成器](_#custom-feed-generators)配合使用。
  31. 所有参数都应该是Unicode对象,除了`categories`,它应该是Unicode对象序列。
  32. [`SyndicationFeed.add_item()`](82e4b5d911d1483ca3008384f7bef69b)
  33. 向具有给定参数的Feed中添加项目。
  34. 必需的关键字参数为:
  35. - `title`
  36. - `link`
  37. - `description`
  38. 可选的关键字参数为:
  39. - `author_email`
  40. - `author_name`
  41. - `author_link`
  42. - `pubdate`
  43. - `comments`
  44. - `unique_id`
  45. - `enclosure`
  46. - `categories`
  47. - `item_copyright`
  48. - `ttl`
  49. - `updateddate`
  50. 将为[自定义Feed生成器](_#custom-feed-generators)存储额外的关键字参数。
  51. 所有参数,如果给定,应该是Unicode对象,除了:
  52. - `pubdate`应为Python [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)对象。
  53. - `updateddate`应为Python [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)对象。
  54. - `enclosure`应为[`django.utils.feedgenerator.Enclosure`](ec868fae877c3b1f0de22227d1d3f80a)的实例。
  55. - `categories`应为Unicode对象序列。
  56. New in Django 1.7:
  57. 已添加可选的`updateddate`参数。
  58. [`SyndicationFeed.write()`](27bd7b7ea86d7c55061c39701c1bbb12)
  59. Outputs the feed in the given encoding to outfile, which is a file-like object.
  60. [`SyndicationFeed.writeString()`](1bafeda259a0d4ce906502a1798608a1)
  61. Returns the feed as a string in the given encoding.
  62. 例如,要创建Atom 1.0订阅源并将其打印到标准输出:

from django.utils import feedgenerator from datetime import datetime f = feedgenerator.Atom1Feed( … title=”My Weblog”, … link=”http://www.example.com/“, … description=”In which I write about what I ate today.”, … language=”en”, … author_name=”Myself”, … feed_url=”http://example.com/atom.xml“) f.add_item(title=”Hot dog today”, … link=”http://www.example.com/entries/1/“, … pubdate=datetime.now(), … description=”

Today I had a Vienna Beef hot dog. It was pink, plump and perfect.

“) print(f.writeString(‘UTF-8’)) <?xml version=”1.0” encoding=”UTF-8”?>

```

自定义Feed生成器

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

如果Feed格式是完全自定义的,您需要将SyndicationFeed作为子类,并完全替换write()writeString()方法。

但是,如果Feed格式是RSS或Atom分拆(即GeoRSS,Apple的iTunes podcast格式等),则您有了更好的选择。这些类型的Feed通常会向底层格式添加额外的元素和/或属性,并且有一组方法可以SyndicationFeed调用以获取这些额外的属性。因此,您可以对相应的Feed生成器类(Atom1FeedRss201rev2Feed)进行子类化,并扩展这些回调。他们是:

SyndicationFeed.root_attributes(self, )

Return a dict of attributes to add to the root feed element (feed/channel).

SyndicationFeed.add_root_elements(self, handler)

Callback to add elements inside the root feed element (feed/channel). handler is an XMLGenerator from Python’s built-in SAX library; you’ll call methods on it to add to the XML document in process.

SyndicationFeed.item_attributes(self, item)

Return a dict of attributes to add to each item (item/entry) element. The argument, item, is a dictionary of all the data passed to SyndicationFeed.add_item().

SyndicationFeed.add_item_elements(self, handler, item)

Callback to add elements to each item (item/entry) element. handler and item are as above.

警告

如果您覆盖任何这些方法,请务必调用超类方法,因为它们为每种Feed格式添加了必需的元素。

例如,您可能开始实现iTunes RSS Feed生成器,如:

  1. class iTunesFeed(Rss201rev2Feed):
  2. def root_attributes(self):
  3. attrs = super(iTunesFeed, self).root_attributes()
  4. attrs['xmlns:itunes'] = 'http://www.itunes.com/dtds/podcast-1.0.dtd'
  5. return attrs
  6. def add_root_elements(self, handler):
  7. super(iTunesFeed, self).add_root_elements(handler)
  8. handler.addQuickElement('itunes:explicit', 'clean')

显然,对于一个完整的自定义feed类,还有很多工作要做,但上面的例子应该展示基本的想法。

{% endraw %}