配信 (syndication) フィード フレームワーク¶
Django には、RSS と Atom フィードを作成するための高レベルな配信 (syndication) フィード生成フレームワークが付属しています。
任意の配信フィードを作成するには、短い Python クラスを書くだけで済みます。好きなだけフィードを作成できます。
Djangoには、低レベルのフィード生成APIも付属しています。ウェブコンテキストの外や、他の低レベルな方法でフィードを生成したい場合に使用してください。
高レベルのフレームワーク¶
Feed
クラス¶
Feed
クラスは配信フィードを表す Python クラスです。フィードは単純なもの (例えば、"サイトニュース" フィードや、ブログの最新エントリを表示する基本的なフィード) もあれば、より複雑なもの (例えば、特定のカテゴリに属する全てのブログエントリを表示するフィード (カテゴリは可変)) もあります。
フィードクラスは django.contrib.syndication.views.Feed
のサブクラスです。これらはコードベースのどこにでも置くことができます。
簡単な例¶
この単純な例は、ある警察のニュースサイトから引用したもので、最新の5つのニュースのフィードを記述しています:
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
のサブクラスです。 title
、link
、およびdescription
は、それぞれ標準RSSの<title>
,<link>
,<description>
要素に対応します。items()
は、フィードに含めるべきオブジェクトのリストを返すメソッドです。この例では、Djangoの ORM を使用してNewsItem
オブジェクトを返しますが、items()
は必ずモデルインスタンスを返す必要はありません。Django モデルを使用することで、いくつかの機能が「タダ」で提供されますが、items()
は任意の種類のオブジェクトを返すことができます。- Atom フィードを作成する場合、RSS フィードではなく、
description
属性の代わりにsubtitle
属性を設定してください。例については、後述の Publishing Atom and RSS feeds in tandem を参照してください。
まだやるべきことが一つあります。RSSフィードでは、各 <item>
には <title>
, <link>
, そして <description>
が含まれています。これらの要素にどんなデータを入れるべきか、フレームワークに伝える必要があります。
<title>
と<description>
の内容について、DjangoはFeed
クラスでメソッドitem_title()
とitem_description()
を呼び出そうとします。これらには、オブジェクト自体を表す単一のパラメータitem
が渡されます。これらはオプションであり、デフォルトではオブジェクトの文字列表現が両方に使用されます。タイトルや説明文に特別な書式を設定したい場合は、 Django テンプレート を代わりに使用できます。そのパスは
Feed
クラスのtitle_template
とdescription_template
属性で指定できます。テンプレートはアイテムごとにレンダリングされ、2つのテンプレートコンテキスト変数に渡されます:{{ obj }}
-- 現在のオブジェクト (items()
で返したオブジェクトのいずれか)。{{ site }}
―― 現在のサイトを表すdjango.contrib.sites.models.Site
オブジェクト。これは{{ site.domain }}
や{{ site.name }}
に便利です。Django サイトフレームワークがインストールされていない場合は、これはRequestSite
オブジェクトに設定されます。詳細は、サイトフレームワークのドキュメントの RequestSite のセクション を参照してください。
記述テンプレートを使用した以下の a complex example を参照してください。
-
Feed.
get_context_data
(**kwargs)¶ 必要な変数が2つ以上ある場合、タイトルと説明テンプレートに追加情報を渡す方法もあります。その場合は、
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>
の内容を指定するには、2つの選択肢があります。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への変換をすべて自身で行う責任があります。
複雑な例¶
このフレームワークは、引数を通じて、より複雑なフィードもサポートしています。
たとえば、あるウェブサイトが、都市内の各警察管轄地域の最近の犯罪についてのRSSフィードを提供しているとします。各警察の管轄地域ごとに Feed
クラスを別々に作成するのは愚かなことです。それは DRY原則 に反し、データをプログラミングロジックに結びつけてしまいます。代わりに、配信 (syndication) フレームワークを使用すると、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()
によって返されたオブジェクトです - それが失敗した場合、引数なしでメソッドを呼び出そうとします。
- それができない場合は、クラス属性を使用します。
また、items()
も同じアルゴリズムに従います。最初に items(obj)
を試し、次に items()
、最後に items
クラス属性(リストであるべきです)を試します。
アイテムの説明用にテンプレートを使用しています。これは最小限の例です:
{{ obj.description }}
ただし、フォーマットは必要に応じて追加できます。
以下の ExampleFeed
クラスは、 Feed
クラスのメソッドと属性に関する完全なドキュメントを提供します。
フィードの種類を指定する¶
デフォルトでは、このフレームワークで作成されたフィードはRSS 2.0を使用します。
これを変更するには、次のように Feed
クラスに feed_type
属性を追加します:
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.)
エンクロージャ (Enclosure)¶
ポッドキャストフィードを作成する際に使用されるエンクロージャ (enclosure) を指定するには、item_enclosures
フックを使用するか、またはアイテムごとに1つのエンクロージャのみを持つ場合は代わりに item_enclosure_url
、item_enclosure_length
、item_enclosure_mime_type
フックを使用します。使用例については、以下の ExampleFeed
クラスを参照してください。
言語¶
配信フレームワークによって作成されたフィードは、自動的に適切な <language>
タグ (RSS 2.0) または xml:lang
属性 (Atom) を含みます。デフォルトでは django.utils.translation.get_language()
です。 language
クラス属性を設定することで変更できます。
URL¶
link
メソッド/属性は絶対パス (例: "/blog/"
) または完全修飾ドメインとプロトコルを含むURL (例:"https://www.example.com/blog/"
) を返すことができます。もし link
がドメインを返さない場合、配信フレームワークは SITE_ID 設定
に従って、現在のサイトのドメインを挿入します。
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フィードはフィードレベルの "description" を提供しませんが、"subtitle" を提供 する からです。
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 = "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
低レベルのフレームワーク¶
舞台裏では、高水準のRSSフレームワークがフィードのXMLを生成するために、より低水準のフレームワークを使用しています。このフレームワークは単一のモジュールに存在します: django/utils/feedgenerator.py 。
このフレームワークを使用して、低レベルのフィードを生成します。独自のフィードジェネレータサブクラスを作成して feed_type
Feed
オプションで使用することもできます。
SyndicationFeed
クラス¶
feedgenerator
モジュールには以下の基底クラスが含まれています:
サブクラスは以下です:
django.utils.feedgenerator.RssUserland091Feed
django.utils.feedgenerator.Rss201rev2Feed
django.utils.feedgenerator.Atom1Feed
これら3つのクラスは、特定の種類のフィードをXMLとしてレンダリングする方法を知っています。これらはこのインターフェイスを共有しています:
SyndicationFeed.__init__()
与えられたメタデータの辞書でフィードを初期化します。これはフィード全体に適用されます。必須のキーワード引数は以下の通りです:
title
link
description
他にもいくつかのオプションキーワードがあります:
language
author_email
author_name
author_link
subtitle
categories
feed_url
feed_copyright
feed_guid
ttl
__init__
に渡された追加のキーワード引数は、 custom feed generators での使用のために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
追加のキーワード引数は custom feed generators 用に保存されます。
パラメータを指定する場合は、文字列でなければなりません:
pubdate
は Python のdatetime
オブジェクトであるべきです。updateddate
はPythonのdatetime
オブジェクトでなければなりません。enclosures
はdjango.utils.feedgenerator.Enclosure
インスタンスのリストであるべきです。categories
は文字列のシーケンスであるべきです。
SyndicationFeed.write()
- 指定されたエンコーディングでフィードを outfile に出力します。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 podcast format など)の派生形式である場合、より良い選択肢があります。これらのタイプのフィードは、通常、基本となるフォーマットに追加の要素や属性を追加し、 SyndicationFeed
がこれらの追加属性を取得するために呼び出す一連のメソッドがあります。したがって、適切なフィードジェネレータクラス (Atom1Feed
または Rss201rev2Feed
) をサブクラス化し、これらのコールバックを拡張できます。それらは次のとおりです:
SyndicationFeed.root_attributes(self)
- ルートフィード要素 (
feed
/channel
) に追加する属性のdict
を返します。 SyndicationFeed.add_root_elements(self, handler)
- ルートフィード要素 (
feed
/channel
) 内に要素を追加するためのコールバックです。handler
はPythonの組み込みSAXライブラリからのXMLGenerator
です。処理中のXMLドキュメントに追加するには、これに対してメソッドを呼び出します。 SyndicationFeed.item_attributes(self, item)
- 各アイテム (
item
/entry
) 要素に追加する属性のdict
を返します。引数の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")
完全なカスタムフィードクラスを作成するには、まだ多くの作業が必要ですが、上記の例で基本的な考え方を示すことができるはずです。