代码之家  ›  专栏  ›  技术社区  ›  pomo_mondreganto

在中间模型Django的字段上进行注释

  •  1
  • pomo_mondreganto  · 技术社区  · 6 年前

    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 ContestParticipantRelationship 有需要的 task 竞赛 is_solved

    1 回复  |  直到 6 年前
        1
  •  0
  •   willeM_ Van Onsem    6 年前

    可能是这样的:

    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 True False