我正在尝试在Django中制作一个Movie项目。我希望对电影的收视率有一个看法,该看法可以采用单个rate_value,但通过GET返回电影的收视率平均值。
我不知道我应该从哪里开始。我试图在视图和序列化程序中进行一些更改,但是没有起作用。这里是:
views.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)
serializer.py
class RateSerializer(serializers.ModelSerializer):
class Meta:
model = Rate
fields = ('rate_value',)
和model.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)
现在,它可以正确返回单个值。
答案 0 :(得分:0)
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',)
在不进入应用程序体系结构的情况下,可以使用以下模式。电影对象具有计算属性,该属性调用ratings
(提供给电影评分的related_name
)以获取所有相关评分并返回均值。
只要可以提供可序列化的值,就可以将模型的属性用作序列化器字段。
有关Django中模型的related_name的更多信息,请参见此处-What is `related_name` used for in Django?
答案 1 :(得分:0)
尝试这样的事情:
serializers.py
class RateListSerializer(serializers.Serializer):
avg_rate_value = serializers.FloatField()
class RateSerializer(serializers.ModelSerializer):
class Meta:
model = Rate
fields = ("rate_value", "film")
views.py
class RateListView(generics.ListCreateAPIView):
permission_classes = [AllowAny]
def get_queryset(self):
if self.action == "list":
queryset = Film.objects.all()
film_id = self.request.query_params.get("film_id", None)
if film_id is not None:
queryset = queryset.filter(id=film_id)
return queryset.annotate(avg_rate_value=Avg("rate__rate_value"))
return Rate.objects.all()
def get_seializer_class(self):
if self.action == "list":
return RateListSerializer
return RateSerializer