Django:计算平均食谱评分

时间:2021-05-01 15:42:26

标签: django

我正在创建一个允许用户发布食谱的网站。当用户点击一个菜谱时,他们可以看到关于它的更多详细信息,他们还可以评论和评分。我的问题是如何计算这里的平均食谱评分

模型.py

class Recept(models.Model):

    class NewManager(models.Manager):
        def get_queryset(self):
            return super().get_queryset()

    naslov = models.CharField(max_length=100)
    sestavine = models.CharField(max_length=100)
    priprava = models.TextField()
    rec_img = models.ImageField(upload_to='rec_pics', default='default2.jpg')
    datum = models.DateTimeField(default=timezone.now)
    avtor = models.ForeignKey(User, on_delete=models.CASCADE)
    category = models.ForeignKey(Category, on_delete=models.PROTECT, default=1)
    likes = models.ManyToManyField(
        User, related_name="blog_recept", blank=True)
    favorites = models.ManyToManyField(
        User, related_name='favorite', default=None, blank=True)
    newmanager = NewManager()


CHOICES = (
    (1, '1 stars'),
    (2, '2 stars'),
    (3, '3 stars'),
    (4, '4 stars'),
    (5, '5 stars'),

)


class Reviews(models.Model):
    recept = models.ForeignKey(
        Recept, related_name="reviews", on_delete=models.CASCADE)
    user = models.ForeignKey(
        User, related_name="reviews", on_delete=models.CASCADE)
    content = models.TextField(blank=True, null=True)
    stars = models.IntegerField(choices=CHOICES)
    datum = models.DateTimeField(default=timezone.now)

视图.py

class PostDetailView(FormMixin, DetailView):
    model = Recept
    form_class = CommentForm

    def get_success_url(self):
        return reverse('recept-detail', kwargs={'pk': self.object.id})

    def get_context_data(self, **kwargs):

        context = super(PostDetailView, self).get_context_data(**kwargs)

        get_recept = get_object_or_404(Recept, id=self.kwargs['pk'])

        fav = bool
        if get_recept.favorites.filter(id=self.request.user.id).exists():
            fav = True
        total_sestavine = get_recept.vejice()
        total_likes = get_recept.total_likes()
        total_likes2 = get_recept.total_likes2()  # pokliče functions

        liked = False
        if get_recept.likes.filter(id=self.request.user.id).exists():
            liked = True
        if get_recept.likes.exists():
            last_like = get_recept.last_like()
            context['last_like'] = last_like
        else:
            context['last_like'] = 0

        context['total_likes'] = total_likes
        context['total_likes2'] = total_likes2
        context['liked'] = liked
        context['fav'] = fav
        context['total_sestavine'] = total_sestavine
        context['form'] = CommentForm(
            initial={'recept': self.object, 'user': self.request.user})
        return context

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    def form_valid(self, form):
        form.save()
        return super(PostDetailView, self).form_valid(form)

例如,如果一个食谱有 2 条评论,而一个评论有 3 颗星,其他有 5 颗星,则平均值为 4。

1 个答案:

答案 0 :(得分:1)

要计算给定食谱的平均食谱评分,您可以创建如下所示的辅助方法:

from django.db.models import Avg

def calculate_average_rating(recipe):
    average_rating = Reviews.objects.all().filter(recipe=recipe).aggregate(Avg('stars'))['stars__avg']
    return average_rating

说明:

Django 提供了聚合函数,我们可以使用这些函数从查询集中提取平均值、最大值、最小值等。我们已经使用了 Avg 函数。聚合函数 Avg 以字典的形式返回平均值:例如 {'stars__avg': 4}。为了从返回的字典中提取实际值,我们在末尾附加了 ['stars__avg']。