monologistaがオープンソース化されようとしています。
monologistaは、昨年の5月にpateoさんが作って運用しているつぶやき系のwebアプリケーションです。pateoさんはプログラムも書きますが、本職はデザイナさんなのでデザインも素敵です。
Djangoのtrunkで動くようにしてからオープンソース化するとのことで、Djangoのサンプルとしても、社内とかで使うつぶやきWebアプリとしても、期待大なのです。
今、コードを直しつつブログでノウハウを公開されているところですが、丁度拙作のTrackaでも気になっているタイムライン(自分と、自分がフォローしている人の投稿が一覧されるもの)部分について言及されていたので、少し考えてみました。
pateoさんは、タイムラインの生成にQオブジェクトを使って OR を組み立てているようです。
実のところ、SQLには文字列の長さ制限がありますので、大量にORをつなぐと実行時にエラーとなってしまいます。と、いいながら現在Trackaも IN を使っているだけなので微妙に長さが伸びに勢いがないだけで同様の問題を抱えています。
friends = Friend.objects.filter(me__exact=request.user.id).select_related()
friends_id = [f.favorit_id for f in friends] + [request.user.id] #手抜き
Track.objects.filter(tracker__id__in=friends_id).order_by('-created')
Trackaでは、あえてManyToManyFieldを使用せずにUserに対してForeignKeyを二つもったモデルを定義しています。DjangoではManyToManyの関連で利用される中間テーブルはPythonコード側から見えないため、ゴリゴリやりたいときのためにそうしています。
実際のところ、Trackaの場合はこんな感じにすればフォローしている人の数に関わりなく同じSQLになります(まだ検証していないけど…meじゃなくってfavoriteかも…)。
Track.objects.filter(Q(tracker__id=request.user.id) | Q(tracker__friend__me=request.user.id)).order_by('-created')
#trackerはTrack(Postみたいの)を投稿したユーザ
#friendはフォロー関係を表す中間テーブル
#meは中間テーブルでフォローしているユーザ(つまり自分)
大規模になると話は変わってくると思いますが、ある程度まではこの位の気の使い方でいいんじゃないかと思います。
言及していただきありがとうございます。
恥ずかしながらSQLの文字列の長さ制限を知りませんでしたorz
ユーザを大量に作ったりしていろいろ試してみますー。
[Python][Django]モデルフィールドのデフォルト値 ManyToMany? twitterの発言を表示する「ちんまったー」をリリースしました [MacOSX][Python][Django] MacOSXでchm Dynamic URLs in Django wysiwyg - markdown editor In memory of chicagocrime.org Goodbye, ChicagoCrim
1 by pateo
13:38 on
2008-02-03