如何用Exists替代Count为QuerySet添加布尔类型注解?
解决方法
用Exists子查询实现布尔值注解
你可以用Django的Exists查询表达式来生成布尔值的注解,它会在找到第一条符合条件的关联记录后立刻停止查询,比你之前用的Count性能更好,而且直接返回布尔值,不用额外处理。
代码示例:
from django.db.models import Exists, OuterRef UserHasProduct.objects.filter(user=self.request.user).annotate( is_nfr=Exists( Product.objects.filter( id__in=OuterRef('products'), is_nfr=True ) ) )
优势说明
- 直接返回布尔值:
Exists的结果就是True或False,完全匹配你的需求,不用再把整数转成布尔。 - 性能更高效:数据库执行
EXISTS子查询时,只要找到第一个满足is_nfr=True的Product就会终止查询;而Count需要统计所有符合条件的记录数量,关联数据多的时候,前者的查询速度会快很多。
兼容旧版Django的方案
如果你的Django版本低于1.11(Exists是1.11新增的),可以用Case+When把Count的结果转成布尔值:
from django.db.models import Case, When, BooleanField UserHasProduct.objects.filter(user=self.request.user).annotate( is_nfr=Case( When(products__is_nfr=True, then=True), default=False, output_field=BooleanField() ) )
不过这个方案的性能和Count差不多,因为还是要扫描关联记录,优先推荐Exists的方案。
内容的提问来源于stack exchange,提问作者Kevin Renskers
相关产品推荐
相关产品推荐

