Django:如何使用 Django 计算 post 的评分和评论?
Django: how to count the ratings and reviews of a post using django?
我有一个模型 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)
.
获得课程
现在我想在课程列表视图中计算评分,我该如何在使用过滤器时执行此操作?
这是详细视图的样子
@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
对象一起使用。根据您对评级的过滤判断,您还需要使用 filter=
parameter of the Count
object.
我还强烈建议您研究如何正确使用 Q()
object.
综上所述,一个实现您正在寻找的示例:
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"
。对于您的下一个问题,我强烈建议您也分享您正在使用的模型(或至少是其中的相关部分)。
我有一个模型 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)
.
现在我想在课程列表视图中计算评分,我该如何在使用过滤器时执行此操作?
这是详细视图的样子
@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
对象一起使用。根据您对评级的过滤判断,您还需要使用 filter=
parameter of the Count
object.
我还强烈建议您研究如何正确使用 Q()
object.
综上所述,一个实现您正在寻找的示例:
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"
。对于您的下一个问题,我强烈建议您也分享您正在使用的模型(或至少是其中的相关部分)。