Аннотации Django суммой двух значений с несколькими отношениями

У меня 4 модели:

class App(models.Model):
   ...

class AppVersion(models.Model):
   app = models.ForeignKey(App)
   version_code = models.IntegerField()

   class Meta:
        ordering = ('-version_code',)
   ...

class Apk(models.Model):
   version = models.OneToOneField(AppVersion)
   size = models.IntegerField()

class Obb(models.Model):
   version = models.ForeignKey(AppVersion)
   size = models.IntegerField()

AppVersion версия всегда имеет один Apk, но может иметь 0, 1 или 2 Obbс

Я хочу аннотировать QuerySet в целом size из App (который Apk.size + сумма всех Obb.size для данного AppVersion).

Мой App QuerySet выглядит так:

qs = App.objects.filter(is_visible=True)

и подзапрос версий:

latest_versions = Subquery(AppVersion.objects.filter(application=OuterRef(OuterRef('pk'))).values('pk')[:1])

Этот подзапрос всегда дает самую последнюю AppVersion из App.

Итак, какой подзапрос я должен использовать для аннотирования qs с size атрибут рассчитывается, как показано выше?

1 ответ

Как насчет чего-то вроде этого - насколько я понимаю, вы хотите суммировать размеры apk приложений и obb. apk а также obb_setможно заменить на связанное имя поля, если вы его добавили. Я выбрал значения по умолчанию для имени, связанного с django OneToOne и Fk.

from django.db.models import F, Value, Sum, IntegerField

qs = App.objects.filter(
    is_visible=True
).annotate( 
    apk_size=Sum('apk__size'), 
    obb_size=Sum('obb_set__size')
).annotate( 
    total_size=Value( 
    F('apk_size') + F('obb_size'), 
    output_field=IntegerField()
)
Другие вопросы по тегам