python - Django 使用 prefetch_related() 聚合 Avg vs for 循环
问题描述
我有一个 Review 模型,它与 Rating 模型是一对一的关系。用户可以根据六个不同的标准(清洁度、沟通、签到、准确性、位置和价值)给出评级,这些标准被定义为评级模型中的字段。
class Rating(models.Model):
cleanliness = models.PositiveIntegerField()
communication = models.PositiveIntegerField()
check_in = models.PositiveIntegerField()
accuracy = models.PositiveIntegerField()
location = models.PositiveIntegerField()
value = models.PositiveIntegerField()
class Review(models.Model):
room = models.ForeignKey('room.Room', on_delete=models.SET_NULL, null=True)
host = models.ForeignKey('user.User', on_delete=models.CASCADE, related_name='host_reviews')
guest = models.ForeignKey('user.User', on_delete=models.CASCADE, related_name='guest_reviews')
rating = models.OneToOneField('Rating', on_delete=models.SET_NULL, null=True)
content = models.CharField(max_length=2000)
我正在考虑一种计算总体评分的方法,这将是评分模型中每列的平均值。一种方法是使用 Django 的 aggregate() 函数,另一种方法是预取所有评论并循环遍历每条评论以手动计算总体评分。例如,
for room in Room.objects.all()
ratings_dict = Review.objects.filter(room=room)\
.aggregate(*[Avg(field) for field in ['rating__cleanliness', 'rating__communication', \
'rating__check_in', 'rating__accuracy', 'rating__location', 'rating__value']])
ratings_sum = 0
for key in ratings_dict.keys():
ratings_sum += ratings_dict[key] if ratings_dict[key] else 0
或者,简单地循环,
rooms = Room.objects.prefetch_related('review_set')
for room in rooms:
reviews = room.review_set.all()
ratings = 0
for review in reviews:
ratings += (review.rating.cleanliness + review.rating.communication + review.rating.check_in +
review.rating.accuracy + review.rating.location+ review.rating.value)/6
哪种方式在时间复杂度方面更有效并导致更少的数据库调用?
aggregate(Avg('field_name')) 每次函数调用是否在数据库级别生成一个 Avg 查询?
在调用 room.review_set.all() 时,首先使用 prefetch_related() 调用所有房间是否有助于减少查询次数?
解决方案
推荐阅读
- python - 如何在一系列数字上比较各种乘法算法
- django - 使用 rest-auth 从 Django all-auth 中检索给定确认密钥(电子邮件验证)的用户电子邮件地址
- jquery - 更新输入,更新变量,更新表
- c# - 如何在 wpf 中使 WebView 透明?
- java - 使用 Quarkus + JSONB 是否有相当于 Jackson + Spring 的`@JsonView`?
- python - 为什么 sklearn.tree.DecisionTreeClassifier 和 sklearn.ensemble.RandomForestClassifier 不接受分类输入变量?
- html - 字体大小和文本周围链接的大小(高度)
- android - 智能眼镜 Vuzix M300 上的 Android 语音识别
- python - RuntimeError:成本函数在其第 1 个输出中返回 nan 值
- angular - 登录后网址不正确