Django使用过滤器获取多个最新元素

时间:2015-07-27 14:56:23

标签: python django filter

我有两个模型,我想使用haystack在其中搜索。

class Page(models.Model):
    title = models.CharField(max_length=256, unique=True)

    def __unicode__(self):
        return self.title

class PageRevision(models.Model):
    page = models.ForeignKey(Page, related_name='revisions')
    content = models.TextField(blank=True)

    def __unicode__(self):
        return self.page

我想过滤PageRevions,以便获得所有页面的最新页面修订,因此旧版本的页面不会提供搜索结果。 首先,我认为我可以遍历所有页面,然后将最后一个修订版存储在列表中,

all_pages = Page.objects.all()
page_revisions = []
for page in all_pages:
    page_revisions.append(PageRevision.objects.filter(page=page).order_by('-created')[0])

但是haystack需要一个QuerySet对象,所以我需要使用filter方法。

2 个答案:

答案 0 :(得分:0)

您需要对查询集执行联合操作,以合并page_revisions列表中的所有查询集。

QuerySets的union运算符是|,即管道符号。

qs1|qs2   # Union of two querysets 'qs1' and 'qs2'

以上代码返回一个QuerySet ,包含qs1中的所有项目和qs2中的所有项目,同时处理重复项目,即两个QuerySet中的项目只会出现一次在结果中。

因此,我们会在|列表的每个元素上应用page_revisions union运算符,这些元素是lambdareduce()的帮助下的查询集。

combined_queryset = reduce(lambda x,y: x|y, page_revisions) # returns a queryset with all the querysets combined

变量combined_queryset属于QuerySet类型,由列表page_revisions中所有查询集的组合形成。

您现在可以将查询集combined_queryset传递给haystack以获得所需的结果。

注意:您需要将查询集附加到page_revisions列表而不是对象才能使其生效。

在以下代码片段中将[0]更改为[:1]

page_revisions.append(PageRevision.objects.filter(page=page).order_by('-created')[:1])

答案 1 :(得分:0)

您可以做的一件事是获取每个页面的最新页面修订版的ID号,然后查询这些ID:

all_pages = Page.objects.all()
revision_ids = [p.revisions.order_by('-created').first().pk for p in all_pages]
page_revisions = PageRevision.objects.filter(pk__in=revision_ids)

一些警告:

  1. 有很多疑问!
  2. 不处理页面没有修订的情况(但如果需要,可以很容易地进行调整)。