Django子模型关联筛选父模型:获取关联已支付InvoiceAmount的Invoice
Django模型查询问题
我有如下两个Django模型:
Invoice模型
class Invoice(models.Model): name = models.ForeignKey('Patient', on_delete=models.CASCADE)
InvoiceAmount模型
class InvoiceAmount(models.Model): invoice = models.ForeignKey('Invoice', on_delete=models.CASCADE) amount = models.IntegerField(default=0) is_paid = models.BooleanField(default=False)
我需要筛选出关联了至少一个is_paid=True的InvoiceAmount的Invoice实例,但使用以下查询语句无法正常工作:
Invoice.objects.annotate(all_paid=Exists(InvoiceAmount.objects.filter(is_paid=True, id=OuterRef('pk')))).filter(all_paid=True)
问题原因
原查询的错误在于关联条件写错了:id=OuterRef('pk')是将InvoiceAmount的id字段和Invoice的pk做匹配,这两个字段毫无关联。正确的关联应该使用InvoiceAmount的外键字段invoice,关联到Invoice的主键。
正确解决方案
方案1:使用Exists子查询(修正关联条件)
from django.db.models import Exists, OuterRef # 筛选关联了至少一个已支付InvoiceAmount的Invoice Invoice.objects.annotate( has_paid_amount=Exists( InvoiceAmount.objects.filter( invoice=OuterRef('pk'), # 正确关联外键 is_paid=True ) ) ).filter(has_paid_amount=True)
方案2:直接通过反向关联过滤(更简洁)
利用Django的反向关联查询,加上distinct()避免重复结果(当一个Invoice有多个已支付的InvoiceAmount时会产生重复):
Invoice.objects.filter(invoiceamount__is_paid=True).distinct()
内容的提问来源于stack exchange,提问作者Abdul Raffay
相关产品推荐
相关产品推荐

