如何在Django视图中合并两个或多个查询集?
我正在尝试搜索我正在构建的Django网站,在该搜索中,我正在搜索3种不同的模型。为了在搜索结果列表上进行分页,我想使用一个通用的object_list视图来显示结果。但是要做到这一点,我必须将3个查询集合并为一个。
我怎样才能做到这一点?我已经试过了:
result_list = [] page_list = Page.objects.filter(
Q(title__icontains=cleaned_search_term) |
Q(body__icontains=cleaned_search_term))
article_list = Article.objects.filter(
Q(title__icontains=cleaned_search_term) |
Q(body__icontains=cleaned_search_term) |
Q(tags__icontains=cleaned_search_term))
post_list = Post.objects.filter(
Q(title__icontains=cleaned_search_term) |
Q(body__icontains=cleaned_search_term) |
Q(tags__icontains=cleaned_search_term))
for x in page_list:
result_list.append(x)
for x in article_list:
result_list.append(x)
for x in post_list:
result_list.append(x)
return object_list(
request,
queryset=result_list,
template_object_name='result',
paginate_by=10,
extra_context={
'search_term': search_term},
template_name="search/result_list.html")
但这是行不通的。当我尝试在通用视图中使用该列表时出现错误。该列表缺少克隆属性。
有谁知道我如何合并三个列表page_list,article_list
和post_list
?
回答:
将查询集连接到列表是最简单的方法。如果无论如何将对所有查询集命中数据库(例如,由于需要对结果进行排序),则不会增加成本。
from itertools import chainresult_list = list(chain(page_list, article_list, post_list))
使用itertools.chain
比itertools
在C中实现每个列表和一个元素一个一个地循环添加要快。与在串联之前将每个查询集转换为列表相比,它消耗的内存更少。
现在可以按日期对结果列表进行排序(按照hasen j对另一个答案的评论中的要求)。该sorted()函数方便地接受生成器并返回列表:
result_list = sorted( chain(page_list, article_list, post_list),
key=lambda instance: instance.date_created)
如果你使用的是Python 2.4或更高版本,则可以使用attrgetter
而不是lambda。我记得曾经读过关于它更快的文章,但是对于一百万个项目,我没有看到明显的速度差异。
from operator import attrgetterresult_list = sorted(
chain(page_list, article_list, post_list),
key=attrgetter('date_created'))
以上是 如何在Django视图中合并两个或多个查询集? 的全部内容, 来源链接: utcz.com/qa/429783.html