関連オブジェクト

2006年04月13日(木) 11:09

ホスティングや重さの問題でCOREBlog2をあきらめてDjangoでへっぽこblog&CMSを作っているわけですが、どうしても欲しい機能があります。
それは関連コンテンツです。
Plone2に由来する関連コンテンツですが、COREBlog2の関連オブジェクトはPlone2のそれと違い、オブジェクトのタイプによってはコンテンツ内にインライン表示することが出来ます。COREBlog2の人たちがブログに画像を表示していたらそれはきっと関連コンテンツです。
画像ファイルをアップしてイメージタグを用いて表示するのに比べてなにがイイかというと、画像を削除すると関連させていたエントリの表示からも消えるとか、イメージ以外のオブジェクトもインライン表示できたりとか、そんなところです。

なので、野望としては関連コンテンツをこのblogに実装してやるぞ、と。

Djangoにはcontent_typesというModelが備わっていて、各アプリケーションのModelが自動的にそこにしまわれます。
関連コンテンツ用のモデルは次のようにすればブログのエントリと別のモデル(エントリを対象にも出来るけど)に関連を持たせることが可能です。

class RelatedItem(models.Model) :
    content_type = models.ForeignKey(ContentType)
    main_object_id = models.IntegerField(_('main object ID'))
    related_object_id = models.IntegerField(_('related object ID'))
    pub_date = models.DateTimeField(auto_now_add=True)

    class Admin :
        list_display = ('content_type', 'main_object_id', 'related_object_id', 'pub_date')
    class Meta :
        ordering = ("-pub_date",)

    def get_related_object(self):
        try:
            return self.content_type.get_object_for_this_type(pk=self.related_object_id)
        except ObjectDoesNotExist:
            return None

ContentTypeのget_object_for_this_typeというファンクションは対象のContentTypeのテーブルから正しい型でデータを取得してくれます。このModelの場合は、元のコンテンツタイプはblogのEntryであると規定してしまっていますが、もう一つContentTypeをForeignKeyフィールドにとれば、逆から辿ることも出来るようになるでしょう。
こんな調子でとりあえずは画像のModelとダウンロード用ファイルのModelを作りました。
まだアップロードとか関連づけがDjangoの管理画面からしかできませんが、比較的簡単に新しいModelとModel専用の小さなテンプレートの追加が出来るようになっているので、そのうち整理して公開してみようかな。
関連させるModelもDjangoのモデルなので、「最近追加されたなんとか」も簡単に実現可能(ただしModelごちゃまぜは「最近関連させたなんとか」みたいなもの以外は大変そう)。

ローカルの現状動作はこんな感じ(画像と、下の方のファイルへのりんくっぽいやつ)。


Feedbacks

Tags