Суммирование столбцов в Django с помощью связанных полей

Я пытаюсь сделать некоторую агрегацию некоторых столбцов Django, но получаю ошибку, которую не могу понять. Вот мои модели (все, что относится к делу):

class Fillup(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
    date = models.DateField(default=date.today)
    trip_distance = models.FloatField(validators=[MinValueValidator(0.0)])
    car = models.ForeignKey('Car',on_delete=models.CASCADE, related_name='fillups')


class Car(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
    name = models.CharField(max_length=25)

Итак, каждый объект Fillup - это, по сути, бак с бензином в автомобиле, и я хочу получить общее значение столбца trip_distance для каждого автомобиля. Я пробовал несколько способов из различных других страниц StackOverFlow, но, похоже, ничего не работает.

Моя первая попытка заключалась в добавлении этого поля в Car Model:

@property
def distance_driven(self):
    return self.fillups.aggregate(sum('trip__distance'))

Но я получаю следующую ошибку:

TypeError: unsupported operand type(s) for +: 'int' and 'str'

Я также попробовал добавить это в мой сериализатор, но получил ту же ошибку:

distance_driven = serializers.SerializerMethodField()

def get_distance_driven(self, ob):
    return ob.fillups.all().aggregate(sum('trip_distance'))['trip__distance']

Есть ли здесь что-то, что я упускаю? Я не понимаю, почему я получаю эту ошибку при попытке суммировать столбец FloatField.

Любая помощь будет очень признательна!

Для агрегации используется объект Sum [Django-doc], а не встроенный Python sum.

Вы можете получить сумму одного объекта с помощью:

from django.db.models import Sum

return self.fillups.aggregate(total=Sum('trip_distance'))['total']

Если вам нужно сделать это для нескольких записей, лучше .annotate(…) [Django-doc]:

from django.db.models import Sum

Car.objects.annotate(
    total_distance=Sum('fillups__trip_distance')
)

Объекты Car, возникающие из этого кверисета, будут иметь дополнительный атрибут .total_distance с суммой связанных Fillup trip_distances.

Вернуться на верх