python - 如何使用 Django 模型中的函数遍历 SQL 数据库?
问题描述
我需要知道如何在 Django 模型中创建一个函数,该模型遍历 SQL 数据库,特别是另一个模型。
我的 Django 项目包含两个模型,“Accelerator”和“Review”。Accelerator 模型有一个十进制字段“overall_rating”,其值取决于输入到 Review 模型字段之一“overall”中的值的累积。为了完成这项工作,我得出结论,我需要在 Accelerator 模型中创建一个函数,该函数:
- 遍历 Review 模型数据库
- 将 Review.overall 的值添加到满足特定条件的列表中
- 计算列表的总值并将其除以列表长度以确定整体评级的值
Accelerator.overall_rating 的值很容易发生变化(即,只要发布了对该“加速器”的新评论并因此添加了新的 review.overall 值,它就需要更新)。所以我的问题是:
- 在我的加速器模型中插入一个函数会确保它的值根据审查模型输入而变化吗?
- 如果是,遍历我的数据库的审阅模型内容需要什么语法?
(我只在共享代码中包含了相关的模型字段)
class Accelerator(models.Model):
overall_rating = models.DecimalField(decimal_places=2, max_digits=3)
class Review(models.Model):
subject = models.ForeignKey(Accelerator, on_delete=models.CASCADE, blank=False)
overall = models.DecimalField(decimal_places=2, max_digits=3)
解决方案
您通常不会自己计算聚合,而是让数据库来完成。数据库经过优化可以做到这一点。遍历集合将导致数据库需要传达所有相关记录,这将导致使用大量带宽。
如果您的目标是计算平均评分,您可以review_set
使用Avg
聚合 [Django-doc] 聚合,例如:
from django.db.models import Avg
class Accelerator(models.Model):
@property
def average_rating(self):
return self.review_set.aggregate(
average_rating=Avg('overall')
)['average_rating']
如果您需要对大量 s 执行此操作,则上述内容不是很有用Accelerator
,因为这会导致每个 Accelerator
. 但是,您可以annotate(..)
[Django-doc]您的Accelerator
课程,例如使用Manager
[Django-doc]:
from django.db.models import Avg
class AcceleratorManager(models.Manager):
def get_queryset(self):
return super().get_queryset().annotate(
_average_rating=Avg('review__overall')
)
然后我们可以改变Accelerator
类,首先看一下该值是否已经由注释计算:
class Accelerator(models.Model):
objects = models.Manager()
objects_with_rating = AcceleratorManager()
@property
def average_rating(self):
try:
return self._average_rating
except AttributeError:
self._average_rating = result = self.review_set.aggregate(
average_rating=Avg('overal')
)['average_rating']
return result
如果我们因此访问例如Accelerator.objects_with_rating.filter(pk__lt=15)
,我们将批量计算这些Accelerator
s 的平均评分。
将平均值存储在数据库中可能不是一个好主意,因为它会引入数据重复,并且同步数据重复往往是一个难题。
推荐阅读
- sql - 我认为这两个 SQL 查询是相同的,但答案是不同的。有什么区别?
- java - 为什么会出现“线程异常”?
- sql - 一旦我的条件对 postgresql 中的某一行变为真,如何退出 case 表达式
- flutter - 如何在颤振步进器中从子小部件获取文本输入?
- python - Django 模型数据存储
- python - 对 np.array 与 python 列表求和:不支持的操作数类型为 %:'list' 和 'int'
- visual-studio-code - 在不更改 .vscode 文件夹的情况下更改 vscode 配置
- linux - 上传到 Hbase 时数据大小减小
- image - 如何填充图像中的像素间隙
- angular - 如何以角度减少图像的模糊或增加亮度