Как добавить поле в кверисет Django
Я изучаю DRF и пытаюсь сделать сайт, где пользователи могут оставлять отзывы о некоторых продуктах и также оценивать (нравится или не нравится) эти отзывы. Так вот сейчас я застрял в подобной системе. Например, у меня есть такие модели:
class Review(models.Model):
author = models.ForeignKey(User)
text = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
class Reaction(models.Model):
author = models.ForeignKey(User)
review = models.ForeignKey(Review, related_name='reactions')
like = models.BooleanField() # True = like, False = dislike
Я хочу показать список сообщений со счетчиками "нравится" и "не нравится", а также как-то отметить, что зарегистрированному пользователю уже понравилось или не понравилось сообщение. Я сделал представление для списка постов со счетчиками, но не знаю, как включить информацию о том, что пост был оценен пользователем
class ListReviews(generics.ListAPIView):
serializer_class = ProductReviewSerializer
def get_queryset(self):
product_slug = self.kwargs['product_slug']
queryset = Review.objects.filter(product__slug=product_slug).annotate(
likes_count=Count('reactions', filter=Q(reactions__like=True)),
dislikes_count=Count('reactions', filter=Q(reactions__like=False)),
user_reaction=...
)
return queryset
Возможно ли это вообще? Или лучше просто сделать другую конечную точку для получения реакции пользователя для текущей страницы?
Это можно сделать с помощью подзапроса, который выбирает Отзывы, отфильтрованные текущим пользователем, и использует это в качестве аннотации
# You'll need these imports
from django.db.models import Q, Count, OuterRef, Subquery
def get_queryset(self):
product_slug = self.kwargs['product_slug']
user_reactions = Reaction.objects.filter(review=OuterRef('pk'), author=self.request.user)
queryset = Review.objects.filter(product__slug=product_slug).annotate(
likes_count=Count('reactions', filter=Q(reactions__like=True)),
dislikes_count=Count('reactions', filter=Q(reactions__like=False)),
user_reaction=Subquery(user_reactions.values('like')[:1])
)
return queryset
Аннотация user_reaction будет иметь значение True, False или None, если пользователю понравился отзыв, не понравился отзыв или он никак не отреагировал соответственно