我有一个模型course
,我也有一个模型review and rating
,允许用户对特定的课程进行评分。现在我想在筛选时计算每个课程的所有评分。注意:在课程细节视图中,我想出了一种方法来计算像rating_count = CourseRating.objects.filter(course=course, rating__in=["3.0", "4.0", "5.0"]).count()
这样的评级。这只在详细视图中工作,因为我首先使用course = Course.objects.get(slug=course_slug)
获得课程。
现在我想在课程列表视图中计算评分,我如何在使用过滤器时做到这一点?
detail视图是这样的
@login_required
def course_details(request, course_slug):
user = request.user
course = Course.objects.get(slug=course_slug)
reviews_count = CourseRating.objects.filter(active=True, course=course).count()
rating_count = CourseRating.objects.filter(course=course, rating__in=["3.0", "4.0", "5.0"]).count()
这是列表视图的样子注意:这是我想要计算每个课程的所有评级
def index(request):
courses = Course.objects.filter(course_publish_status="published").order_by('?')
models.py
class Course(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
course_title = models.CharField(max_length=100, null=True, blank=True)
slug = models.SlugField(unique=True)
course_category = models.ForeignKey(Category, on_delete=models.DO_NOTHING, null=True, blank=True, related_name="courses")
course_publish_status = models.CharField(max_length=10000, choices=COURSE_PUBLISH_STATUS, default="in_review")
class CourseRating(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
course = models.ForeignKey(Course, on_delete=models.CASCADE, null=True, related_name="ratings")
rating = models.CharField(max_length=1000, choices=USER_COURSE_RATING)
review = models.TextField()
date = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
def __str__(self):
return f"{self.course.course_title} - {self.rating}"
class Meta:
verbose_name = "Course Reviews and Ratings"
你要找的是Aggregation
文档有一些很好的(和快速的)例子如何实现它。您正在寻找使用.annotate
与Count
对象。根据您对评级的过滤判断,您还需要使用Count
对象的filter=
参数。我还强烈建议您研究一下如何正确使用Q()
对象。
说了这么多,一个例子来实现你正在寻找的:
courses = Course.objects.filter(
course_publish_status="published",
).annotate(
rating_count=Count(
'ratings',
filter=Q(ratings__rating__in=["3.0", "4.0", "5.0"])
)
).order_by("?")
请记住,我认为你的ForeignKey
上有related_name="ratings"
。对于你的下一个问题,我强烈建议你也分享你正在使用的模型(或者至少是它们的相关部分)。