Django: Как вывести среднее значение всех оценок с помощью django?

Я создаю функцию, где пользователи могут оценивать книгу с помощью django, я достиг той части, где пользователи могут оценивать книгу с помощью формы с фронтэнда и она сохраняется в бэкэнде. Теперь я хочу получить способ отображения среднего значения всех оценок, которые ставит пользователь. Например, допустим, есть usera - 1.0, userb - 3.0, userc -5.0. Я хочу отобразить среднее значение, которое равно 3.0, и я не знаю, как этого добиться. Позвольте мне вывести часть кода, который я написал ниже

models.py

USER_BOOK_RATING = (
        ("1.0", "★☆☆☆☆ (1/5)"),
        ("2.0", "★★☆☆☆ (2/5)"),
        ("3.0", "★★★☆☆ (3/5)"),
        ("4.0", "★★★★☆ (4/5)"),
        ("5.0", "★★★★★ (5/5)"),
)

class BookRating(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    book = models.ForeignKey(Book, on_delete=models.CASCADE, null=True)
    rating = models.CharField(max_length=1000, choices=USER_BOOK_RATING)
    review = models.TextField()

view.py - только то, что я делаю, выводит все отзывы, но не среднее значение звездной оценки

Во-первых, я бы использовал DecimalField вместо CharField - вы не можете выполнять математические операции над строкой. Это будет выглядеть примерно так:

from decimal import Decimal

USER_BOOK_RATING = (
        (Decimal("1.0"), "★☆☆☆☆ (1/5)"),
        (Decimal("2.0"), "★★☆☆☆ (2/5)"),
        (Decimal("3.0"), "★★★☆☆ (3/5)"),
        (Decimal("4.0"), "★★★★☆ (4/5)"),
        (Decimal("5.0"), "★★★★★ (5/5)"),
)

class BookRating(models.Model):
    # rest of model as before
    rating = models.DecimalField(max_digits=2, decimal_places=1, choices=USER_BOOK_RATING)

После того, как вы изменили это, вы можете использовать aggregate и Avg - что-то вроде:

from django.db.models import Avg

# Get average score of all books
average = BookRating.objects.aggregate(avg=Avg('duration'))
# Returns a dict - if using Decimal fields you'll get something like:
# {'avg': Decimal('3.81818181818182')}

Добавьте свою фильтрацию перед вызовом aggregate и, надеюсь, это приблизит вас к искомому решению.

Вы также можете посмотреть на django-star-ratings - библиотеку, которую мы написали на работе, потому что нам постоянно требовалось реализовать звездные рейтинги. Не уверен, что она точно подходит - в ней нет отзывов - но она близка к тому, чего вы хотите достичь, или, по крайней мере, вы можете увидеть источник для вдохновения.

Вернуться на верх