在中间模型django的字段上注释

问题描述 投票:1回答:1

我有以下方案:

class User(AbstractUser):
    pass

class Task(models.Model):
    pass

class Contest(models.Model):
    tasks = models.ManyToManyField('Task',
                               related_name='contests',
                               blank=True,
                               through='ContestTaskRelationship')

    participants = models.ManyToManyField('User',
                                      related_name='contests_participated',
                                      blank=True,
                                      through='ContestParticipantRelationship')

class ContestTaskRelationship(models.Model):
    contest = models.ForeignKey('Contest', on_delete=models.CASCADE)
    task = models.ForeignKey('Task', on_delete=models.CASCADE)
    cost = models.IntegerField()


class ContestParticipantRelationship(models.Model):
    contest = models.ForeignKey('Contest', on_delete=models.CASCADE)
    user = models.ForeignKey('User', on_delete=models.CASCADE)
    task = models.ForeignKey('Task', on_delete=models.CASCADE, related_name='contests_participants_relationship')
    is_solved = models.BooleanField()

现在我得到了contest对象,需要通过tasks字段获取所有任务,rach注释用户数解决了它。所以,我需要用所需的ContestParticipantRelationship计算task的数量,需要将contestis_solved设置为True。如何进行这样的查询?

django many-to-many django-queryset
1个回答
0
投票

可能是这样的:

from django.db.models import IntegerField, Value, Sum
from django.db.models.functions import Cast, Coalesce


Task.objects.filter(
    contests__contest=some_contest,
).annotate(
    nsolved=Cast(Coalesce(
        Sum('contests_participants_relationship__is_solved'), Value(0)
    ),IntegerField())
)

所以在这里我们首先过滤这个任务的竞赛是some_contest的事实。然后我们在Sum(..)列上执行is_solved。由于存在角落情况,这可能是NULL(如果没有用户尝试等等),那么我们将其转换为0,而且我们将其转换为IntegerField,因为否则某些情况可能是用TrueFalse注释,以防零或一个用户解决它。

© www.soinside.com 2019 - 2024. All rights reserved.