Предположим, у меня есть следующие модели:
class Thing(models.Model):
name = models.CharField(max_length=100)
ratings = models.ManyToManyField('auth.User', through='Rating')
class Rating(models.Model):
user = models.ForeignKey('auth.User')
thing = models.ForeignKey('Thing')
rating = models.IntegerField()
Так что у меня много вещей, и каждый пользователь может оценить каждую вещь.У меня также есть представление, показывающее список всех вещей (и их огромное количество) с рейтингом, который пользователь присвоил каждому из них.Мне нужен способ получить все данные из базы данных: объекты Thing с дополнительным полем user_rating
, взятым не более чем из одного (потому что у нас есть фиксированный пользователь) связанный объект рейтинга.
Тривиальное решение выглядит так:
things = Thing.objects.all()
for thing in things:
try:
thing.user_rating = thing.ratings.objects.get(user=request.user).rating
except Rating.DoesNotExist:
thing.user_rating = None
Но недостаток этого подхода очевиден: если у нас будет 500 вещей, мы сделаем 501 запрос к базе данных.За одну страницу.На пользователя.И это самая просматриваемая страница сайта.Эта задача легко решается с помощью SQL JOIN, но на практике у меня есть более сложная схема, и я, безусловно, выиграю от фреймворка модели Django.Итак, вопрос: возможно ли сделать этот Django-способ?Было бы очень странно, если бы не это, учитывая, что такие задачи очень распространены.
Как я понял, ни annotate()
, ни select_related()
мне здесь не помогут.