Django:获取查询集的补集

9

我获取了一个特定模型的查询集,现在想要获取它的补集,也就是该模型中所有不在前述查询集中的实例。

我该如何实现这个功能?


为了给您提供最精确的补集获取方式,最好有您想要补集链的Django queryset。 - Chris Pratt
我想要一个适用于任何查询集的东西。 - Ram Rachum
1个回答

14

简短的解决方案

qs = Model.objects.filter(...) # qs with objects to exclude
result = Model.objects.exclude(pk__in=qs.values_list('pk', flat=True))

更加DRY的解决方案

如果您想多次使用该逻辑,建议将其封装在一个方法中。这是我在自定义查询集中使用的示例:

class QuerysetUtils:
    def get_queryset_complement(self, method):
        return self.exclude(pk__in=method().values_list('pk', flat=True))


class ExpirableQueryset(QuerysetUtils, models.query.QuerySet):
    def expired(self):
        return self.filter(expiration__lte=timezone.now())

    def unexpired(self):
        return self.get_queryset_complement(self.expired)

2
请注意,以下内容是作为子查询执行的,即不会生成要排除的所有 id 的列表(否则可能会对性能造成潜在影响)。 - second
2
这是最简洁的解决方案吗? - Ram Rachum
也许对于你的使用情况有更好的选择,但正如@Chris Pratt所说,如果你能展示一些代码,那将会很有帮助。 - Bernhard Vallant
@RamRachum - 好吧,那么上面的解决方案应该是最简单的;正如第二个指出的那样,数据库只会被访问一次,因为Django将在SQL子查询中获取要排除的主键。 - Bernhard Vallant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接