Django 1.8和1.9,邮政数据库。
我有一个Contest模型,它可以有许多由Entry提交的相关对象。

class Contest(models.Model):
    title = models.CharField(max_length=50)

class Entry(models.Model):
    contest = models.ForeignKey(Contest, related_name="entries")
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

我想得到一个所有Users对象的列表,用Contest标记进行注释,指示特定complete是否为每个user提交了Entry
from django.db.models import Case, When, BooleanField, Value

user = User.objects.get(...)
contests = Contest.objects.annotate(
    complete=Case(
        When(entries__user=user, then=Value(True)),
        default=Value(False),
        output_field=BooleanField(),
    )
)

Contest上的预期结果如下(对于user1):
python - Django:通过多个多值关系进行注释-LMLPHP
但是,我得到的是重复的元素,这取决于每个contestsEntries的数量(请注意竞赛4和竞赛5):
python - Django:通过多个多值关系进行注释-LMLPHP
在这一点上,我尝试将Contest添加到queryset的末尾,但是由于考虑了新的distinct()注释,我仍然得到了complete的副本。
python - Django:通过多个多值关系进行注释-LMLPHP
因为我在Django>=1.8上使用Postgres,所以我想使用Contest 4。不幸的是,在distinct("id")中设置为False
python - Django:通过多个多值关系进行注释-LMLPHP
这就是我决定提出这个问题的部分。关于如何从当前结果到预期结果(第一个表)的指针?我是否通过使用条件注释而忽略了某些内容?

最佳答案

您可以同时添加order_bydistinct以获得所需的结果。

contests = Contest.objects.annotate(
    complete=Case(
        When(entries__user=user, then=Value(True)),
        default=Value(False),
        output_field=BooleanField(),
    )
).order_by('id', '-complete').distinct('id')

请注意distinct文档中的以下注释
指定字段名时,必须在QuerySet中提供order_by()order_by()中的字段必须以相同顺序以distinct()中的字段开头。
例如,SELECT DISTINCT ON (a)column a中的每个值提供第一行。如果不指定顺序,将得到任意行。
因此,首先按id对结果进行排序,然后按complete的降序排序(否则将得到顶部有complete=False的行)。然后,使用distinct('id')保留每个id的第一行并删除其他行。

关于python - Django:通过多个多值关系进行注释,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35789487/

10-15 20:50