Среднее для рейтингов в Django - PullRequest
1 голос
/ 09 марта 2020

Я работаю над приложением, используя django и python в школе. Это приложение для написания обзоров и оценки фильмов. Я хотел бы внедрить систему рейтингов, чтобы я мог отображать средний рейтинг фильма на основе рейтинга, приведенного в обзорах. На данный момент этот код дает рейтинг в порядке убывания всех отзывов, а не средний. Например, если я получу два отзыва о мове ie, со счетом 1 и 5, я получу оба, но не тот, который говорит 3. Пожалуйста, помогите!

В models.py:

class Film(models.Model):
    title = models.CharField(max_length=100)
    title_short = models.CharField(max_length=17, default=None, null=True)
    plot = models.TextField()
    poster = models.ImageField(default="default.png", upload_to="posters")
    release_date = models.DateField(blank=True, null=True)
    date_posted = models.DateTimeField(default=timezone.now)


class Review(models.Model):
    writer = models.ForeignKey(User, on_delete=models.CASCADE)
    reviewed_film = models.ForeignKey(Film, on_delete=models.CASCADE)

    title = models.CharField(max_length=100)
    content = models.TextField()
    rating = models.IntegerField(
        default=1, validators=[MinValueValidator(1), MaxValueValidator(5)]
    )

In views.py:

class ToplistListView(LoginRequiredMixin, ListView):
    model = Review
    template_name = "board/toplist.html"
    context_object_name = "films"

    def get_queryset(self):
        return Review.objects.annotate(avg_rating=Avg('rating')).order_by('-avg_rating')

1 Ответ

1 голос
/ 09 марта 2020

Вы получаете средний рейтинг по каждому обзору, который, конечно, просто даст вам оценку за этот обзор, поскольку у каждого обзора есть только один рейтинг. Среднее число одного числа - это просто число.

Я думаю, что вы хотите получить среднее значение для всех оценок фильма. Поэтому вам нужен запрос, который выглядит примерно так:

Flim.objects.annotate(avg_rating=Avg('review_set__rating')).order_by('-avg_rating')

Кроме того, вы можете изменить имя review_set (по умолчанию для поиска по внешнему ключу, если не установлено связанное имя) на любое другое вы хотите, установив related_name='reviews' или как хотите, чтобы он вызывался в определении FK.

Итак:

reviewed_film = models.ForeignKey(Film, related_name='reviews', on_delete=models.CASCADE)

ETA: если вы сделаете это изменение, ваш запрос станет:

Flim.objects.annotate(avg_rating=Avg('reviews__rating')).order_by('-avg_rating')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...