Django: получить строку на основе максимального значения значения поля внешнего ключа

#django #django-queryset

#django #django-набор запросов

Вопрос:

У меня есть две модели

 class Status(models.Model)
    name = models.CharField(max_length=25)
    rank = models.PositiveSmallIntegerField()

class MyModel(models.Model)
    user = models.ForeignKey(User)
    category = models.CharField(max_length=2)
    status = models.ForeignKey(Status)
    entry_date = models.DateField()

--- Status table ---
id   |   name     |   rank 
1    |   poor     |   1
2    |   below avg|   2
3    |   avg      |   3
4    |   above avg|   4
5    |   good     |   5


--- MyModel table ---
user   |  category | status_id | entry_date
user1  |  A        | 1         | ..
user1  |  A        | 2         | ..
user1  |  A        | 3         | ..
user1  |  B        | 2         | ..
  

Для данного пользователя я хочу получить максимальный статус ранжирования для каждой категории. Итак, для пользователя 1 мне нужны следующие две строки

 user   |  category | status_id | entry_date
user1  |  A        | 3         | ..
user1  |  B        | 2         | ..
  

Как я могу этого добиться? Я пытался MyModel.objects.annotate(max_rank=Max('status__rank')).filter(status__rank=F('max_rank'))
но он выдает «Неизвестный столбец ‘myapp_status.rank’ в ‘предложении having'».

Ответ №1:

поскольку вы хотите сгруппировать по пользователю и категории, я думаю, вам нужно что-то вроде

  MyModel.objects.values('user', 'category' 
     ).annotate(max_rank=Max('status__rank'))
  

поскольку может быть несколько записей с максимальным рангом, я не думаю, что вы сможете получить entry_date из запроса агрегации, подобного этому

Смотрите документы для получения дополнительной информации