#django #model #relationship
#django #Модель #отношение
Вопрос:
Итак, у меня есть две модели Django ‘Movie’ и ‘Rating’, я хочу, чтобы поле фильма avg_rating было средним значением оценок, принадлежащих этому полю с номером фильма. Я также хочу, чтобы avg_rating в поле movie обновлялся каждый раз, когда добавляется обзор. Я новичок в Django, поэтому я действительно не знаю, с чего начать. Ниже приведен файл моих моделей. любая помощь была бы оценена
from django.db import models
from django.db.models import IntegerField, Model
from django.core.validators import MaxValueValidator, MinValueValidator
class Movie(models.Model):
title = models.CharField(max_length=200)
date = models.DateField()
image = models.CharField(max_length=200)
details = models.CharField(max_length=500)
genre = models.CharField(max_length=50)
duration = models.CharField(max_length=20)
classification = models.CharField(max_length=50)
avg_rating = models.PositiveSmallIntegerField(
default=1,
validators=[
MaxValueValidator(5),
MinValueValidator(0)
]
)
class Rating(models.Model):
number = models.IntegerField(
default=1,
validators=[
MaxValueValidator(5),
MinValueValidator(0)
]
)
comment = models.CharField(max_length=200, default='')
movie = models.ForeignKey(Movie, default=1, on_delete=models.CASCADE)
Ответ №1:
Один из простых способов — определить в вашем Movie
классе метод, возвращающий среднюю оценку вашего Movie
объекта. Итак, вам просто нужно добавить следующий код в вашу модель:
from django.db import models
from django.db.models.functions import Coalesce
from django.db.models import IntegerField, Model
from django.core.validators import MaxValueValidator, MinValueValidator
class Movie(models.Model):
title = models.CharField(max_length=200)
date = models.DateField()
image = models.CharField(max_length=200)
details = models.CharField(max_length=500)
genre = models.CharField(max_length=50)
duration = models.CharField(max_length=20)
classification = models.CharField(max_length=50)
def rating_avg(self):
return Rating.objects.filter(movie=self).aggregate(
avg=Coalesce(models.Avg('number'), 0),
)['avg']
Обратите внимание, что среднее значение рейтинга поля удалено из Movie
полей. Теперь у вас есть метод, который вы можете вызывать для каждого Movie
объекта, и этот метод вернет вам среднюю оценку для этого объекта в определенное время.
Пример:
movie_object = Movie.objects.first()
if movie_object:
print(movie_object.rating_avg()) # will print average rating of that particular object
И если вы используете модель Serializer
или a ModelForm
for Movie
, вы также можете добавить имя этого метода к полям этой модели Serializer
или ModelForm
для вычисления средней оценки для каждого объекта всякий раз, когда вы вызываете представление для этого объекта (т. Е. fields = ['title', ..., 'rating_avg']
).