Y
Y
Yzurgzd2020-08-06 19:58:01
Django
Yzurgzd, 2020-08-06 19:58:01

How to get the rating set by the user in 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 = "Рейтинги"


In Views I want to get the rating set by the current (authorized user)
apps = App.objects.filter(draft=False).annotate(
            rating_user=models.Count("ratings",
                                     filter=models.Q(ratings__user=self.request.user))
        )


Full 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


How can I better display the rating (star) set by the current user?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey Tikhonov, 2020-08-07
@tumbler

App.objects.prefetch_related(Prefetch('rating_set', queryset=Rating.objects.filter(user=self.request.user))

app.rating_set[0].star

About something like this. From the App perspective, ranking is a one-to-many relationship, so select_related won't work. prefetch_related will make for each application an array of all ratings, and specifying queryset in Prefetch will reduce this array to the current user's rating (if any).
From the side of serializers, it is best to file SerializerMethodField further

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question