【问题标题】:Django append query results to query setDjango 将查询结果附加到查询集
【发布时间】:2011-11-17 17:13:37
【问题描述】:

在我正在构建的视图中,我需要查阅多个数据库。我想要做的是使用 on query_set 的结果来搜索另一个数据库表。

我有正常的 mydb1_query_set,我现在需要的是这样的:

for row in mydb1_query_set:
        mydb2_query_set = Mytable.objects.filter(id=row.id)

所以我在迭代时不断添加到最初为空的 mydb2_query_set 中。我意识到没有QuerySet.append,那么我该如何实现我想要的呢?非常感谢任何帮助...

【问题讨论】:

  • 包含一些模型描述可能会很好——因为我不喜欢将查询强制到列表中——尤其是在循环中。因此,根据您想要的结果以及您正在使用的内容 - 可以使用注释、分组或其他方式聚合查询。但是对于你正在使用的东西,比如 Mytable.objects.filter(id__in=list(mydb1_query_set)) .. 其中 mydb1_query_set 只是一个 ID 列表。这对你来说可能是完全错误的 - 但我只想向你展示循环和列表转换可能不是唯一/最佳选择。

标签: django django-queryset


【解决方案1】:
qs1= <QuerySet [<User: 1@gmail.com>, <User: 2@gmail.com>]>
qs2= <QuerySet [<User: 3@gmail.com>, <User: 4@gmail.com>]>
qs3 = qs1 | qs2

回复:

qs3 = <QuerySet [<User: 1@gmail.com>, <User: 2@gmail.com>, <User:3@gmail.com>, <User: 4@gmail.com>]>

编辑:文档链接:

https://docs.djangoproject.com/en/2.1/ref/models/querysets/#operators-that-return-new-querysets

【讨论】:

  • 虽然这可能会回答作者的问题,但它缺少一些解释性文字和文档链接。如果没有围绕它的一些短语,原始代码 sn-ps 并不是很有帮助。您可能还会发现how to write a good answer 非常有帮助。请编辑您的答案。
  • 注意 :- 它只适用于querysets with same model
  • 这个答案有问题。如果你想用日期过滤,假设最新的日期元素将是第一个,它不会正确显示。
【解决方案2】:

使用 python 的内置 itertools 模块对我来说效果最好。

from itertools import chain

qs1 = Mytable.objects.filter(id=2)
qs2 = Mytable.objects.filter(id=3)

all_queries = chain(qs1, qs2)

这里是文档,如果您需要一些参考资料:https://docs.python.org/3/library/itertools.html#itertools.chain

【讨论】:

  • 你的会强制计算两个查询,而qs1 | qs2 会产生一个查询。
  • @OmarAbouMrad,我无法让qs1 | qs2 解决方案正常工作,对于我来说,两个查询不是问题,但如果它适用于其他人,请注意这一点
【解决方案3】:

使用list 代替queryset,然后您可以根据需要使用appendextend

mydb2_query = []
for row in mydb1_query_set:
    mydb2_query.extend(list(Mytable.objects.filter(id=row.id)))

【讨论】:

  • 这与我的想法一致,但为什么我会收到 AttributeError: 'list' object attribute 'extend' is read-only 错误?
  • 但这很慢,你不强制查询集在每个项目中命中数据库吗?
  • 是的,每个项目都有一个数据库查询。我试图回答“如何将结果附加到查询集?”这个问题,但没有给出最佳解决方案。如果存在性能问题,那么您可以尝试不同的方法,正如 Storm 在上面的评论中建议的那样。
  • 我正在使用fromList = ThingShareLink.objects.filter(from_share_id=share_id) toList = ThingShareLink.objects.filter(to_share_id=share_id) context['object_list'] = list(chain(fromList, toList))
【解决方案4】:

Django 的 Managers 对象 provide a default method 称为 .get_queryset(),它允许您在它之后连接额外的查询:

queryset = MyModel.objects.get_queryset()
if username:
    queryset = queryset.filter(username=username)
if country:
    queryset = queryset.filter(country=country)

您可以轻松使用.query 属性获取SQL,例如:

>>> print(queryset.query)
SELECT `myapp_mymodel`.`id`, `myapp_mymodel`.`username`, `myapp_mymodel`.`country` FROM `myapp_mymodel` WHERE `myapp_mymodel`.`country` = foo

【讨论】:

    猜你喜欢
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 2020-09-28
    • 2012-01-01
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多