首页 > 解决方案 > 返回模型中值的平均值而不是每个值

问题描述

我正在尝试在 django 中制作电影项目。我想对电影的收视率有一个看法,它可以采用单个 rate_value 但通过 GET 返回电影收视率的平均值。

我不知道我应该从哪里开始。我尝试了视图和序列化程序的一些更改,但没有奏效。以下是:

视图.py:

class RateListView(generics.ListCreateAPIView):
    permission_classes = [AllowAny]
    serializer_class = RateSerializer
    lookup_url_kwarg = 'rateid'

    def get_queryset(self):
        rateid = self.kwargs.get(self.lookup_url_kwarg)
        queryset = Rate.objects.filter(film = rateid)
        # .aggregate(Avg('rate_value'))

        if queryset.exists():
            return queryset
        else:
            raise Http404

    def post(self, request, *args, **kwargs):
        serializer = RateSerializer(data = request.data)

        if serializer.is_valid():
            if Film.objects.filter(pk = self.kwargs.get(self.lookup_url_kwarg)).exists():
            serializer.save(film_id = self.kwargs.get(self.lookup_url_kwarg))
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            raise Http404

    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

序列化程序.py

class RateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Rate
        fields = ('rate_value',)

和模型.py

class Rate(models.Model):
    film = models.ForeignKey(Film, on_delete = models.CASCADE)
    rate_value = models.IntegerField(validators = [
                        MinValueValidator(1),
                        MaxValueValidator(10)
                        ]
    )

    def __str__(self):
        return str(self.film.title) + str(self.rate_value)

现在它正确返回单个值。

标签: pythondjango

解决方案


class Film(models.Model:
    ...

    @property
    def mean_rating(self):
        ratings = self.ratings.all().values_list('rate_value', flat=True)
        if ratings:
            return sum(ratings)/len(ratings)
        # return a separate default value here if no ratings

class Rate(models.Model):
    film = models.ForeignKey(Film, on_delete = models.CASCADE, related_name='ratings')
    rate_value = models.IntegerField(validators = [
                        MinValueValidator(1),
                        MaxValueValidator(10)
                        ]
    )

...

class FilmSerializer(serializers.ModelSerializer):
    class Meta:
        model = Film
        fields = ('id','name','mean_rating',)

无需深入了解您的应用程序架构,这里有一个可以使用的模式。ratingsFilm 对象有一个计算属性,该属性调用related_name提供给电影评级的 ,以获取所有相关评级并返回平均值。

只要提供可序列化的值,模型的属性就可以用作序列化器字段。

有关 Django 中模型的 related_name 的更多信息,请参阅此处 - What is `related_name` used in Django?


推荐阅读