You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django如何筛选外键关联Discount全部为is_deleted的Product(不可用exclude)

实现方案

可通过Django ORM的聚合查询实现,全程在数据库层面完成计算,单条SQL即可执行,大表场景下性能远高于exclude生成的嵌套子查询。

方案1:ORM聚合查询(推荐,无需写原生SQL)

通过annotate统计每个Product关联的未删除Discount数量,筛选数量为0的结果即可:

from django.db.models import Count, Q

result = Product.objects.annotate(
    # 统计当前产品关联的、未删除的Discount总数
    undelete_discount_count = Count('discount', filter=Q(discount__is_deleted=False))
).filter(undelete_discount_count=0)

边界情况调整

上述查询默认会包含没有关联任何Discount的Product,如果只需要筛选「有关联Discount且所有Discount均为已删除」的产品,调整过滤条件即可:

result = Product.objects.annotate(
    undelete_discount_count = Count('discount', filter=Q(discount__is_deleted=False))
).filter(undelete_discount_count=0, discount__isnull=False).distinct()

方案2:原生SQL查询(性能最高,超大数据量可选)

如果数据量达到千万级,可直接写原生SQL执行,配合索引可达到最优性能:

result = Product.objects.raw('''
    SELECT p.* FROM product p
    LEFT JOIN discount d ON p.id = d.product_id AND d.is_deleted = FALSE
    GROUP BY p.id
    HAVING COUNT(d.id) = 0
''')

性能优化建议

给Discount表的product_id和is_deleted字段创建联合索引,可将上述查询的耗时降低90%以上,适合大表场景。

内容的提问来源于stack exchange,提问作者Tiancheng Liu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 21:18:00