Django:为具有多个评级标准的评论网站生成评级平均值
Django: Generate averages for ratings for a review site with multiple rating critera
正在使用 Python(3.8) 和 Django 开发一个项目,尝试实施具有多个标准的审查系统。
注意:我已经搜索了一段时间,但没有阅读任何专门解决我的问题的内容。
我有 3 个模型:
from django.db import models
from django.conf import settings
from django.urls import reverse
# Create your models here.
class Board(models.Model):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=100)
def __str__(self):
return self.name
def get_reviews_count(self):
return Review.objects.filter(company__board=self) .count()
def get_last_review(self):
return Review.objects.filter(company__board=self) .order_by('created_at') .first()
class Company(models.Model):
name = models.CharField(max_length=255, unique=True)
#bio = models.TextField(max_length=4000)
last_updated = models.DateTimeField(auto_now_add=True)
board = models.ForeignKey(Board, on_delete = models.CASCADE, related_name='companies')
starter = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='companies',
)
views = models.PositiveIntegerField(default=0)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('company_detail', args=[str(self.id)])
def get_recent_reviews(self):
return self.reviews.order_by('-created_at')
def get_last_ten_reviews(self):
return self.reviews.order_by('-created_at')[:10]
class Review(models.Model):
RATING_CHOICES = (
('1', '1'),
('2', '2'),
('3', '3'),
('4', '4'),
('5', '5'),
)
STAY = (
('less than 6 months', 'less than 6 months'),
('6 months', '6 months'),
('10 months', '10 months'),
('12 months', '12 months'),
('More than 1 year', 'More than 1 year'),
)
YES_NO = (
('Yes', 'Yes'),
('No', 'No'),
)
SECURITY = (
('100%', '100%'),
('75%', '75%'),
('50%', '50%'),
('25%', '25%'),
('0%', '0%'),
('Still waiting', 'Still waiting'),
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete = models.CASCADE, related_name='reviews')
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete = models.CASCADE, null=True, related_name='+')
company = models.ForeignKey(Company, on_delete = models.CASCADE, related_name='reviews')
address = models.CharField(max_length=200, blank=False, default="")
length_of_stay = models.CharField(max_length=20, choices=STAY, blank=False)
#Apartment Condition
move_in_condition = models.CharField(max_length=5,choices=RATING_CHOICES)
#Landlord Interaction
treatment = models.CharField(max_length=5, choices=RATING_CHOICES, blank=False, default ="3")
response_speed = models.CharField(max_length=5, choices=RATING_CHOICES, blank=False, default ="3")
maintenance_quality = models.CharField(max_length=5, choices=RATING_CHOICES, blank=False, default ="3")
security_deposit_returned = models.CharField(max_length=5, choices=SECURITY, blank=False, default ="1")
#put text "ignore if still waiting"
is_this_a_fair_amount = models.CharField(max_length=5, choices=YES_NO, blank=False, default="1")
would_you_recommend = models.CharField(max_length=5, choices=YES_NO, blank=False, default="1")
additional_comments = models.TextField(max_length=4000)
def __str__(self):
return self.address
Views.py
def board_companies(request, pk):
board = get_object_or_404(Board, pk=pk)
companies = board.companies.order_by('-last_updated') .annotate(replies=Count('reviews'))
return render(request, 'companies.html', {'board': board, 'companies': companies})
def company_reviews(request, pk, company_pk):
company = get_object_or_404(Company, board__pk=pk, pk=company_pk)
company.views += 1
company.save()
return render(request, 'company_reviews.html', {'company': company})
用户post对一家公司发表了评论,评论表单中有很多标准。
我想对一些标准进行平均,以获得评论 post 的总体评分,该评分将与每条评论一起显示 post。
然后对公司的所有综合评分进行平均,显示在公司评论页,公司列表页。
然后单独找到每个单独标准的总平均值,并将其显示在总体评分下方的公司评论页面上(治疗平均值、response_speed 平均值等)
提前致谢!
尝试使用 F 表达式并将聚合与注释结合起来:
# Annotate with average of multiple rating columns,
# then aggregate all overall ratings and each individual rating of all reviews
Company.objects.annotate(overall_rating = Avg(
F('move_in_condition') +
F('treatment') +
F('response_speed') +
F('maintenance_quality') / 4
)).aggregate(
Avg('overall_rating'),
Avg('move_in_condition'),
Avg('treatment'),
Avg('response_speed'),
Avg('maintenance_quality')
)
这整个语句执行您指定的所有三件事。
您可能需要在 Avg 函数中指定 output_field
参数,以防出现错误
Havent' 对此进行了测试,但我直接基于文档:
https://docs.djangoproject.com/en/2.2/ref/models/expressions/#f-expressions
https://docs.djangoproject.com/en/2.2/topics/db/aggregation/#aggregating-annotations
正在使用 Python(3.8) 和 Django 开发一个项目,尝试实施具有多个标准的审查系统。
注意:我已经搜索了一段时间,但没有阅读任何专门解决我的问题的内容。
我有 3 个模型:
from django.db import models
from django.conf import settings
from django.urls import reverse
# Create your models here.
class Board(models.Model):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=100)
def __str__(self):
return self.name
def get_reviews_count(self):
return Review.objects.filter(company__board=self) .count()
def get_last_review(self):
return Review.objects.filter(company__board=self) .order_by('created_at') .first()
class Company(models.Model):
name = models.CharField(max_length=255, unique=True)
#bio = models.TextField(max_length=4000)
last_updated = models.DateTimeField(auto_now_add=True)
board = models.ForeignKey(Board, on_delete = models.CASCADE, related_name='companies')
starter = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='companies',
)
views = models.PositiveIntegerField(default=0)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('company_detail', args=[str(self.id)])
def get_recent_reviews(self):
return self.reviews.order_by('-created_at')
def get_last_ten_reviews(self):
return self.reviews.order_by('-created_at')[:10]
class Review(models.Model):
RATING_CHOICES = (
('1', '1'),
('2', '2'),
('3', '3'),
('4', '4'),
('5', '5'),
)
STAY = (
('less than 6 months', 'less than 6 months'),
('6 months', '6 months'),
('10 months', '10 months'),
('12 months', '12 months'),
('More than 1 year', 'More than 1 year'),
)
YES_NO = (
('Yes', 'Yes'),
('No', 'No'),
)
SECURITY = (
('100%', '100%'),
('75%', '75%'),
('50%', '50%'),
('25%', '25%'),
('0%', '0%'),
('Still waiting', 'Still waiting'),
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete = models.CASCADE, related_name='reviews')
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete = models.CASCADE, null=True, related_name='+')
company = models.ForeignKey(Company, on_delete = models.CASCADE, related_name='reviews')
address = models.CharField(max_length=200, blank=False, default="")
length_of_stay = models.CharField(max_length=20, choices=STAY, blank=False)
#Apartment Condition
move_in_condition = models.CharField(max_length=5,choices=RATING_CHOICES)
#Landlord Interaction
treatment = models.CharField(max_length=5, choices=RATING_CHOICES, blank=False, default ="3")
response_speed = models.CharField(max_length=5, choices=RATING_CHOICES, blank=False, default ="3")
maintenance_quality = models.CharField(max_length=5, choices=RATING_CHOICES, blank=False, default ="3")
security_deposit_returned = models.CharField(max_length=5, choices=SECURITY, blank=False, default ="1")
#put text "ignore if still waiting"
is_this_a_fair_amount = models.CharField(max_length=5, choices=YES_NO, blank=False, default="1")
would_you_recommend = models.CharField(max_length=5, choices=YES_NO, blank=False, default="1")
additional_comments = models.TextField(max_length=4000)
def __str__(self):
return self.address
Views.py
def board_companies(request, pk):
board = get_object_or_404(Board, pk=pk)
companies = board.companies.order_by('-last_updated') .annotate(replies=Count('reviews'))
return render(request, 'companies.html', {'board': board, 'companies': companies})
def company_reviews(request, pk, company_pk):
company = get_object_or_404(Company, board__pk=pk, pk=company_pk)
company.views += 1
company.save()
return render(request, 'company_reviews.html', {'company': company})
用户post对一家公司发表了评论,评论表单中有很多标准。
我想对一些标准进行平均,以获得评论 post 的总体评分,该评分将与每条评论一起显示 post。
然后对公司的所有综合评分进行平均,显示在公司评论页,公司列表页。
然后单独找到每个单独标准的总平均值,并将其显示在总体评分下方的公司评论页面上(治疗平均值、response_speed 平均值等)
提前致谢!
尝试使用 F 表达式并将聚合与注释结合起来:
# Annotate with average of multiple rating columns,
# then aggregate all overall ratings and each individual rating of all reviews
Company.objects.annotate(overall_rating = Avg(
F('move_in_condition') +
F('treatment') +
F('response_speed') +
F('maintenance_quality') / 4
)).aggregate(
Avg('overall_rating'),
Avg('move_in_condition'),
Avg('treatment'),
Avg('response_speed'),
Avg('maintenance_quality')
)
这整个语句执行您指定的所有三件事。
您可能需要在 Avg 函数中指定 output_field
参数,以防出现错误
Havent' 对此进行了测试,但我直接基于文档: https://docs.djangoproject.com/en/2.2/ref/models/expressions/#f-expressions https://docs.djangoproject.com/en/2.2/topics/db/aggregation/#aggregating-annotations