Django: Как применить Count к результатам `distinct` QuerySet?
У меня есть следующие модели:
class Exercise(models.Model):
name = models.CharField(max_length=300)
class UserWorkout(models.Model):
user = models.ForeignKey(User)
class WorkoutSet(models.Model):
exercise = models.ForeignKey(Exercise)
user_workout = models.ForeignKey(UserWorkout, related_name="sets")
date_time = models.DateTimeField(default=timezone.now)
Это упрощенные модели для приложения для тренировок, где пользователь начинает UserWorkout с набором объектов Exercise, затем для каждого упражнения он создает несколько объектов WorkoutSet для записи веса/времени и т.д.
Что я хочу ответить: Учитывая конкретного пользователя, сколько раз каждое упражнение было выполнено им? Я хочу посчитать все связанные объекты WorkoutSet в 1 UserWorkout как 1.
Вот что я имею сейчас:
# 1. Get all Exercise objects performed by the user using WorkoutSet:
qs = Exercise.objects.filter(workoutset__user_workout__user=user)
# 2. Select the ID and Name only and annotate with the workout ID
qs = qs.values('id', 'name').annotate(workout_id=F('workoutset__user_workout__id'))
# 3. Get the distinct of both exercise ID and Workout ID
qs = qs.distinct('id', 'workout_id')
Теперь набор запросов имеет следующие (правильные) данные, которые очень близки к тому, что я хочу:
In [44]: for x in qs:
...: print(x)
...:
{'id': 3, 'workout_id': UUID('755925da-9a43-490c-9ffa-3222acd1dcfa'), 'name': 'Ab Rollout'}
{'id': 3, 'workout_id': UUID('bc59c55b-9adc-47c7-9790-2e5d8b21f956'), 'name': 'Ab Rollout'}
{'id': 3, 'workout_id': UUID('c23c80ea-4408-45d8-bf05-b2d699bee11f'), 'name': 'Ab Rollout'}
{'id': 3, 'workout_id': UUID('cd7b6daf-f4f9-4486-bb21-5f3ad10ef578'), 'name': 'Ab Rollout'}
{'id': 5, 'workout_id': UUID('bc59c55b-9adc-47c7-9790-2e5d8b21f956'), 'name': 'Triceps Extensions'}
{'id': 6, 'workout_id': UUID('3b560d16-d7c0-40d5-8978-a1153bba5b7b'), 'name': 'Bench Press'}
{'id': 6, 'workout_id': UUID('bc59c55b-9adc-47c7-9790-2e5d8b21f956'), 'name': 'Bench Press'}
{'id': 6, 'workout_id': UUID('d0b2a656-d64c-41a8-9c77-fa24974b39a9'), 'name': 'Bench Press'}
{'id': 9, 'workout_id': UUID('bc59c55b-9adc-47c7-9790-2e5d8b21f956'), 'name': 'Bent-over Rows'}
{'id': 9, 'workout_id': UUID('c3e4d35d-62f9-43bb-920c-3b337a86f972'), 'name': 'Bent-over Rows'}
{'id': 11, 'workout_id': UUID('0b0cfd83-7c01-4a2e-b67b-70164b640763'), 'name': 'Bicep Curls'}
{'id': 11, 'workout_id': UUID('16d56358-41a8-497d-89ab-fc561ad9f778'), 'name': 'Bicep Curls'}
{'id': 11, 'workout_id': UUID('714c5dbb-0a75-43b7-a3e5-eb266ce52efa'), 'name': 'Bicep Curls'}
{'id': 11, 'workout_id': UUID('77cc63db-b738-4a1c-9ff6-b65d8e141274'), 'name': 'Bicep Curls'}
{'id': 11, 'workout_id': UUID('834137b0-d2d6-48a4-af6e-b6dcbe7b0d5c'), 'name': 'Bicep Curls'}
{'id': 11, 'workout_id': UUID('f43bcf23-40ae-4904-bf9d-afe7068c0d39'), 'name': 'Bicep Curls'}
{'id': 14, 'workout_id': UUID('bc59c55b-9adc-47c7-9790-2e5d8b21f956'), 'name': 'Squats'}
Что я не могу сделать сейчас, так это получить количество каждого упражнения. Я пытался агрегировать/аннотировать, но получаю следующие ошибки:
NotImplementedError: annotate() + distinct(fields) is not implemented.
NotImplementedError: aggregate() + distinct(fields) not implemented.
Вопрос: Как я могу добавить подсчеты каждого упражнения, чтобы вышеприведенный набор запросов стал выглядеть следующим образом:
{'id': 3, 'name': 'Ab Rollout', 'count': 4}
{'id': 5, 'name': 'Triceps Extensions', 'count': 1}
{'id': 6, 'name': 'Bench Press', 'count': 3}
{'id': 9, 'name': 'Bent-over Rows', 'count': 2}
{'id': 11, 'name': 'Bicep Curls', 'count': 6}
{'id': 14, 'name': 'Squats', 'count': 1}