当前位置: 首页 > 知识库问答 >
问题:

利用多个FK属性进行查询集过滤

黄骏喆
2023-03-14

我的情况:

我有django模型主机和模型包(名称和版本),其中有FK主机模型。现在我需要过滤所有主机,其中有包的特定名称和特定版本…因此,类似host.objects.filter(name=“best_package”,version__in=['1.0','2.0'])这样的操作非常简单,但是我需要对几个包重复这个操作,这样我就可以得到一个版本中包含每个希望的包的主机。

我尝试了两个方法,但都失败了,第一个是在for循环中应用filter,它很丑,但很有效,尽管我很高兴,我发现这不是一个稳定的解决方案,我接下来应用的一些查询有时会失败…是啊。有时候!正如我对自己所说的那样,我不会在Django ORM魔法的洞里走得更深,我尝试用Q构建查询。

pckgs_query = reduce(
    operator.and_,
    (
        Q(packages__name=name, packages__version__in=versions)
        for name, versions in pckgs_dict.items()
    )
 )
hosts = Host.objects.filter(pckgs_query)

谢了!

共有1个答案

陈季
2023-03-14

这不起作用的原因是因为您每次都限制相同的包。如果键是'Best_Package''Other_Package',那么应该有一个相关的包,其名称为'Best_Package''Other_Package',但是由于包只有一个名称,这当然会失败。

我们可以用另一种方法来解决这个问题:我们首先过滤包,以检索与字典中的一个条目匹配的所有包,然后对这些包进行计数,从而检查相关包的数量是否与字典中的元素数量相同:

from django.db.models import Count, Q

pckgs_query = Q(
    *[Q(package_set__name=name, package_set__version__in=versions)
      for name, versions in pckgs_dict.items()],
    _connector=Q.OR
)

hosts = Host.objects.filter(pckgs_query).annotate(
    num_packages=Count('package_set')
).filter(
    num_packages=len(pckgs_dict)
)

因此,这将只返回安装了所有包的主机,因为如果缺少包,num_packages将小于len(pckgs_dict)

 类似资料:
  • myBatis查询多个id(我居然回答用对象来传递...) Page<UserPoJo> getUserListByIds(@Param("ids") List<Integer> ids); <!--根据id列表批量查询user--> <select id="getUserListByIds" resultType="com.guor.UserPoJo"> select * from s

  • 我正在尝试向gremlin顶点添加多个属性。每次我都有不同数量的属性和不同的属性,所以我需要根据Map使查询动态以创建或更新属性。我发现了这个gremlin python-将多个但未知数量的属性添加到顶点,并尝试做同样的事情,但我实例化了一个jansugraph,但我得到了一个错误。任何想法都将非常受欢迎。 下面是直接用gremlin控制台写的,然后我会翻译成java代码。 而我得到的错误是 任何

  • 我有一些文档在嵌套对象中有嵌套对象: 在这里,主文档有几个嵌套的对象(标记),对于每个标记有几个嵌套的对象(事件)。 我希望获得transfer_processed类型的事件在transfer类型的标记之后60000毫秒内发生的所有文档。为此,我需要查询tags.at、tags.type、tags.events.at和tags.events.type。我不知道如何查询:我只查询tags.event

  • 问题内容: 我有一个xml映射器-一个选择和一个结果映射器。它的工作没有问题。但是我想使用注释。我的地图绘制者: 所以我确实是这样 我不明白如何在不执行另一个sql查询的情况下通过注释映射我的集合。作为所有示例,我假设需要再执行一个查询。请帮忙。 问题答案: AFAIK,如果您使用带注释的映射,则不能使用。 在文档中,有关的用法, 到复杂类型的collection属性的映射。属性:select是可

  • 问题内容: 我有以下方法: 在这里,我依次调用三种方法,这依次命中数据库并获取我的结果,然后对从数据库命中获得的结果进行后处理。我知道如何通过使用并发调用这三种方法。但是我想用Java 8 来实现。有人可以指导我如何通过并行流实现相同目标吗? 编辑 我只想通过Stream并行调用方法。 问题答案: 您可以利用这种方式:

  • 我需要一个带有System_id、name、description等的Registered_Systems表。现在,每个系统可以有n个属性,我计划将它们存储在子表Registered_System_Attributes(System_id、Attribute_name、Attribute_Value)中,外键为Registered_Systems.System_id 由于属性必须与系统相关联,所以