Feedjack 読む (4)
どこを辿って今どこにいるか分からなくなったのでまず整理。
今は fjlib.get_paginator 手続きの中。呼び出しの階層としては
- views.mainview
- fjlib.page_context
- fjlib.get_paginator
- fjlib.page_context
なカンジ。一瞬 get_paginator を飛ばしかけて中に入ったのか。ログも結構滅茶苦茶だし。
とりあえず get_paginator の続き
以下のあたりが中断点か
if site.order_posts_by == 2: localposts = localposts.order_by('-date_created', '-date_modified') else: localposts = localposts.order_by('-date_modified')
Site の order_posts_by という列の値で並び順を云々しているように読める。ちなみに models.py における列の定義は以下のような形になっている。
order_posts_by = models.IntegerField(_('order posts by'), default=1, \ choices=SITE_ORDERBY_CHOICES)
デフォは 1 との事。データベース API リファレンスによれば "-" が付いたら降順との事なので日付が新しい順に並ぶ、という事になりますな。
で、以降は後始末。
paginator = ObjectPaginator(localposts.select_related(), \ site.posts_per_page) try: object_list = paginator.get_page(page) except InvalidPage: if page == 0: object_list = [] else: raise Http404 return (paginator, object_list)
おそらくは
- ObjectPaginator なオブジェクトを select_related された Post なオブジェクトとページごとのポストの数 (これは Site の属性) を元に生成
- page で指定されたオブジェクトの並びを object_list に格納
- 例外処理
を経て paginator と object_list を戻す、という事ですか。
戻り
get_paginator 手続きの呼び出しと object_list の状態による処理の振り分けが以下
paginator, object_list = get_paginator(site, sfeeds_ids, \ page=page, tag=tag, user=user_id) if object_list: # This will hit the DB once per page instead of once for every post in # a page. To take advantage of this the template designer must call # the qtags property in every item, instead of the default tags # property. user_obj, tag_obj = get_posts_tags(object_list, sfeeds_obj, \ user_id, tag) else: user_obj, tag_obj = None, None
ええと、とりあえず真偽な式はブール演算 (bool operation)によれば
- None
- 0
- 空のシーケンス(文字列、tuple、リスト)
- 空のマップ型(辞書)
は偽と見るとの事。で、object_list が真判定であれば get_posts_tags 手続きを呼び出している。引数は
- object_list (これは表示対象の Post なクエリセット?)
- sfeeds_ids (Site からたぐれる Subscriber のクレリセット)
- user_id (引数として page_context 手続きに渡される)
- tag (引数として page_context 手続きに渡される)
の4つ。そろそろモデルのリレーションがきちんとイメージできてないと苦しそう。
続き
ぼちぼち進める事に。とりあえず Readingl Gauche 方面は明日がっつりヤる予定。で、続きは fjlib.get_posts_tags なんですが何故にこんなコトしてるのか、と言いつつ models.py を見てみると
tags = models.Tag.objects.extra(\ select={'post_id':'%s.%s' % (\ connection.ops.quote_name('feedjack_post_tags'), \ connection.ops.quote_name('post_id'))}, \ tables=['feedjack_post_tags'], \ where=[\ '%s.%s=%s.%s' % (\ connection.ops.quote_name('feedjack_tag'), \ connection.ops.quote_name('id'), \ connection.ops.quote_name('feedjack_post_tags'), \ connection.ops.quote_name('tag_id')), \ '%s.%s IN (%s)' % (\ connection.ops.quote_name('feedjack_post_tags'), \ connection.ops.quote_name('post_id'), \ ', '.join([str(post.id) for post in object_list]))])
ええと字面で見るに Tag な行を extra で取得、となるのか。なんで非推奨な extra 使ってるのだろうか、と思い models.py 見てみたら無いし (> feedjack_post_tags にあたるモデル)。そりゃこうするしか無いわな。
おそらくベースで SQL に直してみるとこんな感じ??
select feedjack_post_tags.post_id from feedjack_tag, feedjack_post_tags where feedjack_tag.id = feedjack_post_tags.tag_id and feedjack_post_tags.post_id IN (... object_list の post.id のリスト);
日本語にできん (駄目
ってかこれ、違うな。
select feedjack_tag.*, feedjack_post_tags.post_id
みたいなカンジなのかなぁ。こっちが当たりっぽい。ちょっと今日は限界です。なんか進捗悪い今日この頃です。