如何找到两个Django查询集的交集?

Pau*_*ite 26 python django django-models

我有一个带有两个自定义管理器方法的Django模型.每个都根据对象的不同属性返回模型对象的不同子集.

class FeatureManager(models.Manager):

    def without_test_cases(self):
        return self.get_query_set().annotate(num_test_cases=models.Count('testcase_set')).filter(num_test_cases=0)

    def standardised(self):
        return self.get_query_set().annotate(standardised=Count('documentation_set__standard')).filter(standardised__gt=0)
Run Code Online (Sandbox Code Playgroud)

(两者testcase_setdocumentation_set参考ManyToManyField其他型号秒.)

有没有办法获得一个查询集,或只是一个对象列表,这是每个管理器方法返回的查询集的交集?

lqc*_*lqc 54

在大多数情况下,您可以编写(利用QuerySet的"Set"部分):

intersection = Model.objects.filter(...) & Model.objects.filter(...)
Run Code Online (Sandbox Code Playgroud)

这没有很好的记录,但应该表现得几乎完全像在两个查询的条件上使用AND条件.相关代码:https://github.com/django/django/blob/1.8c1/django/db/models/query.py#L203


Cau*_*ons 22

你可以这样做:

intersection = queryset1 & queryset2
Run Code Online (Sandbox Code Playgroud)

要做到工会只需更换&|


tup*_*pan 15

根据Django 1.11,现在可以使用函数intersection()

>>> qs1.intersection(qs2, qs3)
Run Code Online (Sandbox Code Playgroud)

  • 现在应该就是答案。 (2认同)

小智 5

我相信qs1.filter(pk__in = qs2)应该能正常工作。对于我来说,这似乎也适用于类似情况,这很有意义,并且生成的查询看起来很合理。(如果您的一个查询集使用values()而不选择主键列或一些奇怪的东西,我相信它会中断,但是...)


S.L*_*ott 4

重构

class FeatureManager(models.Manager):

    @staticmethod
    def _test_cases_eq_0( qs ):
       return qs.annotate( num_test_cases=models.Count('testcase_set') ).filter(num_test_cases=0)

    @staticmethod
    def _standardized_gt_0( qs ):
        return qs.annotate( standardised=Count('documentation_set__standard') ).filter(standardised__gt=0)

    def without_test_cases(self):
        return self._test_cases_eq_0( self.get_query_set() )

    def standardised(self):
        return self._standardized_gt_0( self.get_query_set() )

    def intersection( self ):
        return self._test_cases_eq_0( self._standardized_gt_0( self.get_query_set() ) )
Run Code Online (Sandbox Code Playgroud)

  • 无论它是否解决了他的问题,它仍然没有回答如何找到两个查询集的交集,这是谷歌在搜索“django junction of querysets”时返回的第一个链接 (12认同)