在不同命名的字段上排序两个不同的模型

时间:2012-01-20 23:17:49

标签: python django postgresql sorting

我有两种模式:PostType1PostType1

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?

2 个答案:

答案 0 :(得分:4)

因此,如果您的计划是对两个查询集的并集进行排序,则必须使用sorted方法。我会选择类似的东西:

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

答案 1 :(得分:1)

每个查询都可以使用order_by执行排序:

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

如果要对整个结果进行排序,可以使用自定义迭代器而不是chain。仅适用于两个模型的示例(尽管不一定是最干净的模型):

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建议使用sorted也会有效,但AFAIK会在排序过程中检索数据库中的所有项目,这可能与您有关,也可能不是。