【发布时间】:2020-05-09 13:29:43
【问题描述】:
假设我有以下模型:
class Invoice(models.Model):
...
class Note(models.Model):
invoice = models.ForeignKey(Invoice, related_name='notes', on_delete=models.CASCADE)
text = models.TextField()
我想选择有一些注释的发票。我会像这样使用annotate/Exists 编写它:
Invoice.objects.annotate(
has_notes=Exists(Note.objects.filter(invoice_id=OuterRef('pk')))
).filter(has_notes=True)
这很好用,只过滤带有注释的发票。但是,这种方法会导致字段出现在查询结果中,这我不需要并且意味着性能更差(SQL 必须执行子查询 2 次)。
我意识到我可以像这样使用extra(where=) 写这个:
Invoice.objects.extra(where=['EXISTS(SELECT 1 FROM note WHERE invoice_id=invoice.id)'])
这将产生理想的 SQL,但通常不鼓励使用 extra / 原始 SQL。
有没有更好的方法来做到这一点?
【问题讨论】:
标签: python django django-models django-queryset django-annotate