【发布时间】:2020-09-16 23:31:23
【问题描述】:
我有以下两个 Django 模型:
class Parent(models.Model):
name = models.CharField(max_length=50)
children = models.ManyToManyField("Child", through="ParentChild")
def __str__(self):
return self.name
class Child(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
假设我的数据库中有四个 Parent 对象,其中只有两个有子对象:
for parent in Parent.objects.all():
print(parent, parent.children.count())
# Parent1 3
# Parent2 0
# Parent3 0
# Parent4 1
我的目标是编写一个高效的数据库查询来获取至少有一个孩子的所有父母。实际上,我有数百万个对象,所以我需要它尽可能高效。到目前为止,我已经提出了以下解决方案:
- 使用
prefetch_related
for parent in Parent.objects.prefetch_related("children"):
if parent.children.exists():
print(parent)
# Parent1
# Parent4
- 使用
filter:
for parent in Parent.objects.filter(children__isnull=False).distinct():
print(parent)
# Parent1
# Parent4
- 使用
exclude:
for parent in Parent.objects.exclude(children__isnull=True):
print(parent)
# Parent1
# Parent4
- 使用
annotate和exclude:
for parent in Parent.objects.annotate(children_count=Count("children")).exclude(children_count=0):
print(parent)
# Parent1
# Parent4
这些解决方案中哪个最快?还有另一种更快/更具可读性的方法吗?我看到了一个 django Exists 函数,但它似乎不适用于这个用例。
【问题讨论】:
标签: django django-models django-orm