2012-01-20 7 views
3

私は2つのモデル:PostType1PostType1を持っています。異なる名前のフィールドに2つの異なるモデルをソート

class PostType1(models.Model): 
    ... 
    created_date = models.DateTimeField(_('created date'), blank=True, null=True) 

class PostType2(models.Model): 
    ... 
    publish_date = models.DateTimeField(_('publish date'), blank=True, null=True) 

私は両方取得するためのクエリを行います。

posts_type1 = PostType1.objects.all() 
posts_type2 = PostType2.objects.all() 

私はそれらをチェーンする方法を知っている:

posts = chain(posts_type1,posts_type2) 

私は日付の降順でそれらをソートする方法を探しています。
これは可能ですか?または、私は生のSQLを見ますか?

答えて

3

あなたの計画は、2つのクエリセットの和集合をソートするであれば、あなたはsortedメソッドを使用する必要があります。私は何かのように行くだろう:

sorted(chain(posts_type1, posts_type2), 
     key=lambda x: x.created_date if isinstance(x, PostType1) 
            else x.publish_date) 
+0

私は同じことをしようとしていたが、私のソートされた議論は、間違っていないと少し不器用だった。どうもありがとうございました。 – geros

1

各クエリはorder_byを使用してソートを行うことができます。

posts_type1 = PostType1.objects.all().order_by('-created_date') 
posts_type2 = PostType2.objects.all().order_by('-publish_date') 

あなたは全体の結果をソートしたい場合は、代わりにchainのカスタムイテレータを使用することができます。 sortedを使用しての

def chain_ordered(qs1, qs2): 
    next1 = qs1.next() 
    next2 = qs2.next() 
    while next1 is not None or next2 is not None: 
     if next1 is None: yield next2 
     elif next2 is None: yeild next1 
     elif next1 < next2: 
      yield next1 
      try: 
       next1 = qs1.next() 
      except StopIteration: 
       next1 = None 
     else: 
      yield next2 
      try: 
       next2 = qs2.next() 
      except StopIteration: 
       next2 = None 

StefanoPの提案があまりにも動作しますが、私の知る限り、それはしてもしなくてもよいとすることができる、ソート時にデータベースからすべてのアイテムを取得します:2つのモデルが唯一の(必ずしもクリーン1が)のための例あなたへの懸念

+0

真実私はすべての私のdbをループしたいです。私はStefanoPの方法を好むだろう。あなたの投稿のためにあなたをThnak。 – geros

+0

確かに、彼のソリューションも好きです。マインは、カーソルを使用して行を取得する場合(たとえば、データ全体が大きすぎてメモリに収まらない場合など)にのみ役立ちます。 – mgibsonbr

関連する問題