Рендеринг наибольшего целочисленного значения из трех экземпляров модели в django

У меня есть три модели, которые связаны с одной моделью.

class MyModelParent(models.Model):
      name = models.CharField(max_lenght=36, blank=True)

      def __str__(self):
          return self.name or ""

class MyFirstModel(models.Model):
      mymodelparent = models.ForeignKey(MyModelParent, related_name="first_models", blank=True, Null=True, on_delete=models.CASCADE
      ranking = models.IntegerField(max_lenght=36, blank=True)

      def __str__(self):
          return self.name or ""

class MySecondModel(models.Model):
      mymodelparent = models.ForeignKey(MyModelParent, related_name="second_models", blank=True, Null=True, on_delete=models.CASCADE
      ranking = models.IntegerField(max_lenght=36, blank=True)

      def __str__(self):
          return self.name or ""

class MyThirdModel(models.Model):
      mymodelparent = models.ForeignKey(MyModelParent, related_name="third_models", blank=True, Null=True, on_delete=models.CASCADE
      ranking = models.IntegerField(max_lenght=36, blank=True)

      def __str__(self):
          return self.ranking or ""

Я отображаю MyParentModel в DetailView (CBV) и передаю связанные модели в качестве контекста для отображения поля "рейтинг" отдельных моделей на том же шаблоне.

Теперь мне нужно отобразить тот же самый "рейтинг" в MyParentModel ListView, но я хочу отобразить только тот "рейтинг", который имеет наибольшее значение. Вопрос в том, как я могу сравнить связанные модели 'ranking integer value' и отобразить самую высокую на странице MyParentModel ListView?

Я нахожусь на кривой обучения, поэтому ценю вашу помощь...

Вы можете сравнивать различные поля с помощью Greatest и сравнивать значения самих полей с помощью Max() - aggregation вернет вам единственное наибольшее значение:

from django.db.models import Max
from django.db.models.functions import Greatest

MyModelParent.objects.aggregate(
    max=Greatest(
        Max('first_models__ranking'),
        Max('second_models__ranking'),
        Max('third_models__ranking'),
    )
)

# output: {'max': 230}

Редактировать - Объяснение

В этом запросе есть три части:

  1. Max - находит максимальное значение предоставленного поля, мы используем двойное подчеркивание для доступа к полю ranking связанной модели, потому что ranking не является полем MyModelParent.

  2. Greatest - поскольку Max работает только с полями, мы не можем использовать его для нахождения максимального из максимальных (если это имеет смысл). Вместо этого нам нужно использовать Greatest, которая является функцией DB (тогда как Max живет внутри django.db.models) и возвращает наибольшее значение из указанного списка. Поэтому мы предоставляем ей каждое из наших значений Max из трех различных моделей.

  3. Aggregate - нам нужна только одна наибольшая цифра, и aggregate скомпонует набор запросов в словарь - мы можем добавить к нему другие значения, если захотим. Annotate также можно использовать, если мы хотим, чтобы каждый объект queryset имел доступ к этому значению.

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