Django 布尔值注释返回重复项
Django boolean annotate returning duplicates
我有以下型号:
class Institution(models.Model):
pass
class Headquarter(models.Model):
institution = models.ForeignKey(Institution, related_name='headquarters')
class Audit(models.Model):
headquarter = models.ForeignKey(Headquarter, related_name='audits')
以及以下查询(基本上,如果一个机构至少进行一次审计,则 has_visits 必须为真:
Institution.objects.annotate(
has_visits=models.Case(
models.When(headquarters__audits=None, then=False),
default=True,
output_field=models.BooleanField()
)
)
问题是,如果一个机构有 2 次审计,那么查询集 returns 重复行。我想它与 SQL 级别的连接有关,但我不确定如何更正它。我找到了这个 但我认为 OuterRef 不是我在我的情况下要找的东西。实现此目标的正确方法是什么?
您可以使用 Exists
subquery [Django-doc]:
from django.db.models import Exists, OuterRef
Institution.objects.annotate(
has_visits=<b>Exists(</b>
Audit.objects.filter(<b>headquarter__institution=OuterRef('pk')</b>)
<b>)</b>
)
其他可能有用的方法是让重复项“崩溃”,例如 Max
:
from django.db.models import Max, Value
from django.db.models.functions import Coalesce
Institution.objects.annotate(
has_visits=<b>Coalesce(Max(</b>models.Case(
models.When(headquarters__audits=None, then=False),
default=True,
output_field=models.BooleanField()
)<b>), Value(False))</b>
)
但这可能会降低其可读性和效率。
我有以下型号:
class Institution(models.Model):
pass
class Headquarter(models.Model):
institution = models.ForeignKey(Institution, related_name='headquarters')
class Audit(models.Model):
headquarter = models.ForeignKey(Headquarter, related_name='audits')
以及以下查询(基本上,如果一个机构至少进行一次审计,则 has_visits 必须为真:
Institution.objects.annotate(
has_visits=models.Case(
models.When(headquarters__audits=None, then=False),
default=True,
output_field=models.BooleanField()
)
)
问题是,如果一个机构有 2 次审计,那么查询集 returns 重复行。我想它与 SQL 级别的连接有关,但我不确定如何更正它。我找到了这个
您可以使用 Exists
subquery [Django-doc]:
from django.db.models import Exists, OuterRef
Institution.objects.annotate(
has_visits=<b>Exists(</b>
Audit.objects.filter(<b>headquarter__institution=OuterRef('pk')</b>)
<b>)</b>
)
其他可能有用的方法是让重复项“崩溃”,例如 Max
:
from django.db.models import Max, Value
from django.db.models.functions import Coalesce
Institution.objects.annotate(
has_visits=<b>Coalesce(Max(</b>models.Case(
models.When(headquarters__audits=None, then=False),
default=True,
output_field=models.BooleanField()
)<b>), Value(False))</b>
)
但这可能会降低其可读性和效率。