Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

RSS実装

RSS実装をてきとーにやってみる。
まあー参考までに。
DjangoRSSフレームワークを使うと実は簡単だったり。

RSS配信する元ネタのmodelを作成

とりあえずザックリ。
お決まりですが。あれば作らなくていいですよ。

models.py
class Post(models.Model):
    title = models.CharField(maxlength=200)
    pub_date = models.DateTimeField('date published', auto_now_add=True)
    body = models.TextField()
    tags = models.ManyToManyField(Tag)
    author = models.ForeignKey(User)
    status = models.CharField(maxlength=32, choices=STATUS_CHOICES,radio_admin=True, default='Draft')
    
    class META:
        ordering = ('-pub_date',)
        get_latest_by = 'pub_date'

    class Admin:
        list_display = ('title','pub_date')
        
    def __repr__(self):
        return self.title
    
    def get_absolute_url(self):
        return "/blog/detail/%s/" % (self.id)

タイトルが"title"、記事は"body"とします。
こいつを介してデータが蓄積されるわけです。
でこれらをitemとして配信します。

Feedを作成する

DjangoではFeedフレームワークを提供しています。
RSSFeedを表すFeedクラスを継承することによって簡単に使用することができます。
では先ほどの"Post"を配信してみましょう。

feeds.py
from django.contrib.syndication.feeds import Feed
from blog.blogapp.models import Post

class BlogEntryFeed(Feed):
    title = "weblog"
    link = "http://hogehoge.com/"
    description = "Latest news about Python."
            
    def items(self):
        list =  Post.objects.order_by('-pub_date')[:5]
        return list

基本的には

    def items(self):

このメソッドを実装して終わりです。

    def items(self):
        list =  Post.objects.order_by('-pub_date')[:5]
        return list

これはPostの最新5件を配信しています。

配信URLを作成する

で作ったFeedはどうやって使われるか?って所です。

url.py
feeds = {
    'blog' : BlogEntryFeed,
}

urlpatterns = patterns('',
…
    (r'^rss/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}),
…
)

まず使用するFeedを定義します。
今回は先ほど作成したBlogEntryFeedクラスを'blog'という名前で定義します。

feeds = {
    'blog' : BlogEntryFeed,
}

で実際に配信されるURLは以下

urlpatterns = patterns('',
…
    (r'^rss/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}),
…
)

本来viewのメソッド名を書く所に"django.contrib.syndication.views.feed"と書いています。
これがdjangoの提供しているRSSフレームワークになります。
で更に先ほど定義したfeedのdictを渡しています。
これで"rss/blog"からRSSが配信されるようになります。
実際のフレームワーク内部の処理は

  1. パラメータのurl部の値を取得
  2. 渡されたfeed_dict内に一致するFeedがあるか探す
  3. 存在した場合はそのFeedのitemsメソッドを呼びRSSを作成し返す

といった事をやっています。

あれ?なんか足りない?

RSSで配信するdescriptionとtitleってどうやって判断しているの?って話です。
はい。正直ここをカスタマイズしないと配信しても意味がありません。
わけのわからんものが配信されます。
(正確にはreprの文字列だけど)
マッピングする方法ですがtemplateを使います。

  • title:モデル名_title.html
  • description:モデル名_description.html

という名前でtemplateを用意します。
具体的にタイトルをmodelのフィールドに割り当てるかは

feeds/blog_title.html
{{obj.title}}
feeds/blog_description.html
{{obj.body}}

のようにすれば良いだけです。
Feedクラスを使うと一応細かい制御もできます。
例えばユーザごとにRSS出したいとかね。そーいうのもできます。
もっと詳しく知りたい方はドキュメント読んでください。

実装自体はblogに説明書く時間の1/10ぐらいで終わっちゃうんだよなあ。
うくく。