У меня довольно простые отношения с 3 моделями, и у меня возникают проблемы при построении набора запросов, который возвращает результаты так, как они мне нужны.
Модели:
class Book(models.Model):
name = models.CharField()
class CategoryLabel(models.Model):
name = models.CharField()
class Review(models.Model):
user = models.ForeignKey(User)
book = models.ForeignKey(Book)
labels = models.ManyToManyField(CategoryLabel)
rating = models.IntegerField()
Теперь результаты набора запросовдолжен быть список книг, о которых конкретный пользователь написал рецензию.
Это легко достижимо с помощью books = Book.objects.filter(review__user=user)
Сложность в том, что мне нужно вывести (через сериализатор django rest framework)) список книг, каждая из которых содержит список отзывов только для указанного пользователя, агрегированный средний рейтинг (опять же, только для указанного пользователя) и набор отдельных меток, с которыми были отмечены отзывы.
Итак, что-то вроде этого в JSON:
[
"name": "Book1",
"reviews": [
"review_id1", "review_id2"
],
"average_rating": 3,
"labels": [
"label_id1", "label_id2"
]
]
Что я пробовал до сих пор:
Book.objects.filter(reviews__user=user)
.annotate(average_rating=Avg("reviews__rating"))
.annotate(labels=ArrayAgg("reviews__labels", distinct=True))
Это дает нужный мне формат, ноон объединяет средний рейтинг по всем обзорам, не только по user
и той же истории с ярлыками, он просто включает все ярлыки, примененные во всех обзорах ... РЕДАКТИРОВАТЬ: это не такправда ..
Есть идеи, как этого добиться максимально эффективно?База данных - это PostgreSQL, поэтому можно использовать специальные функции pg.