Как мне создать метод в django моделях, который возвращает сумму поля в той же модели? - PullRequest
0 голосов
/ 08 мая 2020

Я новичок в Django, и в настоящее время у меня есть две подобные модели. Я хочу вычислить в модели Climber, которая возвращает общее количество очков, которые скалолаз заработал, открыв поле climbs_completed. Как я могу go сделать это? Другими словами, как мне суммировать points для каждого Climb в climbs_completed? Есть ли лучший способ сделать это, кроме написания метода? Заранее спасибо!

class Climb(models.Model):
    name = models.CharField(max_length=20, default='')
    grades = [('v'+str(i),'v'+str(i))for i in range(0,13)]
    grade = models.CharField(max_length=3, choices=grades, default='v-1')
    weeks = [(i,i)for i in range(1,13)]
    week = models.IntegerField(choices=weeks, default=0)
    points = models.IntegerField(default=0)

    def __str__(self):
        return self.name

class Climber(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    grades = [('v'+str(i),'v'+str(i))for i in range(0,13)]
    highest_grade = models.CharField(max_length=3, choices=grades, default='v0')
    team = models.ForeignKey(Team, null=True, on_delete=models.SET_NULL)
    climbs_completed = models.ManyToManyField(Climb, blank=True)

    def __str__(self):
        return self.user.username

    # for each climbs_completed, sum up the points
    def total_score(self):
        pass

1 Ответ

1 голос
/ 08 мая 2020

Вы можете использовать Sum и добавить общее количество точек подъема как аннотированное значение, например:

from django.db.models import Sum

climbers = Climber.objects<b>.annotate(total_score=Sum('climbs_completed__points'))</b>
print(climbers.values('pk', <b>'total_score'</b>))

Или вы можете использовать агрегирование в методе total_score, например :

class Climber(models.Model):
    ...

    def total_score(self):
       return self.climbs_completed.<b>aggregate(total_score=Sum('points'))['total_score']</b>

Первый способ более эффективен, если вы хотите получить значения от группы скалолазов и сделать это за одно обращение к базе данных.

...