@Yzurgzd

Как в DRF получить рейтинг поставленный пользователем?

Models
class Rating(models.Model):
    user = models.ForeignKey(
        UserProfile, verbose_name="Имя пользователя", on_delete=models.CASCADE)
    star = models.PositiveSmallIntegerField(
        "Звезда", validators=[MaxValueValidator(5)], default=0)
    app = models.ForeignKey(
        App,
        on_delete=models.CASCADE,
        verbose_name="приложение",
        related_name="ratings"
    )

    def __str__(self):
        return f"{self.star} - {self.app}"

    class Meta:
        verbose_name = "Рейтинг"
        verbose_name_plural = "Рейтинги"


Во Views хочу получить рейтинг поставленный текущим(авторизованным пользователем)
apps = App.objects.filter(draft=False).annotate(
            rating_user=models.Count("ratings",
                                     filter=models.Q(ratings__user=self.request.user))
        )


Полный Views
class AppViewSet(viewsets.ReadOnlyModelViewSet):
    filter_backends = (DjangoFilterBackend, filters.SearchFilter)
    search_fields = ['title', ]
    filterset_class = AppFilter
    pagination_class = PaginationApps

    lookup_field = 'slug'

    def get_queryset(self):
        apps = App.objects.filter(draft=False).annotate(
            rating_user=models.Count("ratings",
                                     filter=models.Q(ratings__user=self.request.user))
        ).annotate(
            middle_star=models.Sum(models.F('ratings__star')) /
            models.Count(models.F('ratings'))
        )
        return apps

    def get_serializer_class(self):
        if self.action == 'list':
            return AppListSerializer
        elif self.action == "retrieve":
            return AppDetailSerializer


Как мне лучше вывести рейтинг(звезду) поставленный текущим пользователем?
  • Вопрос задан
  • 701 просмотр
Пригласить эксперта
Ответы на вопрос 1
tumbler
@tumbler Куратор тега Django
бекенд-разработчик на python
App.objects.prefetch_related(Prefetch('rating_set', queryset=Rating.objects.filter(user=self.request.user))

app.rating_set[0].star

Примерно как-то так. Со стороны App рейтинг это отношение один-ко-многим, так что select_related не прокатит. prefetch_related сделает для каждого приложения массив всех оценок, а указание queryset в Prefetch сократит этот массив до оценки текущего пользователя (если она есть).
Со стороны сериалайзеров дальше лучше всего запилить SerializerMethodField
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы