如何在Django视图中组合两个或多个查询集?

我正在尝试建立一个Django网站的搜索,在这个搜索中,我搜索了三种不同的模型。为了对搜索结果列表进行分页,我想使用通用对象列表视图来显示结果。但要做到这一点,我必须将三个查询集合并为一个查询集

我该怎么做?我试过这个:

结果列表=[]
page_list=page.objects.filter(
Q(标题\uuu icontains=已清理\u搜索\u术语)|
Q(正文内容=已清理的搜索词))
article\u list=article.objects.filter(
Q(标题\uuu icontains=已清理\u搜索\u术语)|
Q(正文内容=已清理的搜索项)|
Q(标记\uuuiCONTAINS=已清理的\uuSearch\uTerm))
post_list=post.objects.filter(
Q(标题\uuu icontains=已清理\u搜索\u术语)|
Q(正文内容=已清理的搜索项)|
Q(标记\uuuiCONTAINS=已清理的\uuSearch\uTerm))
对于第页列表中的x:
结果列表。追加(x)
对于文章列表中的x:
结果列表。追加(x)
对于post_列表中的x:
结果列表。追加(x)
返回对象列表(
要求
queryset=结果列表,
模板\u对象\u name='result',
分页单位=10,
额外上下文={
“搜索词”:搜索词},
模板名称=“搜索/结果”列表.html

但这不起作用。当我尝试在通用视图中使用该列表时,我会出错。列表缺少克隆属性

如何合并这三个列表,page\u listarticle\u listpost\u list

将查询集连接到列表中是最简单的方法。如果所有查询集都会命中数据库(例如,因为需要对结果进行排序),这不会增加进一步的成本

来自itertools导入链的


结果列表=列表(链接(页面列表、文章列表、帖子列表))

使用itertools.chain比循环每个列表并逐个追加元素更快,因为itertools是用C实现的。它也比在连接之前将每个查询集转换为列表消耗更少的内存

现在可以对结果列表进行排序,例如按日期排序(根据hasen j对另一个答案的评论中的要求)。sorted()函数方便地接受生成器并返回列表:

结果\u列表=已排序(
链(页面列表、文章列表、帖子列表),
key=lambda实例:instance.date\u创建)

如果您使用的是Python 2.4或更高版本,那么可以使用attrgetter而不是lambda。我记得读到过关于它速度更快的文章,但我没有看到百万物品列表中有明显的速度差异

来自操作员导入属性的


结果列表=已排序(
链(页面列表、文章列表、帖子列表),
key=attrgetter('date_created'))

发表评论