django - Django中的聚合
问题描述
我在 Django 中有以下模型:
class A(models.Model):
nr = models.IntegerField()
class B(models.Model):
points = models.IntegerField()
class C(models.Model):
a = models.ForeignKey(A, on_delete=models.CASCADE)
b = models.ForeignKey(B, on_delete=models.CASCADE)
因此,对于每个 A,C 中都有很多条目,对于每个 B,C 中也有很多条目。但是对于 C 中的每个条目,A 中只有一个条目,B 中只有一个条目。
我想总结给定 A 的 B.points,但我必须超过 C。
我怎么能在 Django 中做到这一点?如果有帮助,我会知道如何在 SQL 中做到这一点?
解决方案
您可以.annotate(..)
[Django-doc]A
s,例如:
从 django.db.models 导入 Sum A.objects.annotate( total_points=Sum('c__b__points') )
例如,如果您总是想注释您的A
对象,您可以为此定义一个管理器:
class WithPointsManager(models.Manager):
def get_queryset(self):
return super().get_queryset().annotate(
total_points=Sum('c__b__points')
)
然后在A
类上定义这个管理器,比如:
class A(models.Model):
nr = models.IntegerField()
objects = WithPointsManager()
所以现在如果你执行 a A.objects.all()
,A
s 将有一个total_points
属性。请注意,这当然会在数据库端产生一定的成本。
A
然后由此产生的所有对象QuerySet
都将包含一个额外的.total_points
属性,该属性包含与 a 相关的所有B
s 的总和,该 aC
与该相关A
。
或者对于给定的A
对象,您可以.aggregate(..)
[Django-doc],例如:
from django.db.models import Sum
some_a.c_set.aggregate(
total_points=Sum('b__points')
)['total_points']
这将返回与 相关的s集合points
中相关B
对象的总和。C
some_a
推荐阅读
- xamarin.forms - 警报管理器本地通知 - 打开通知时如何打开特定页面?
- visual-studio-2019 - 运行 npm 命令 prebuild Visual Studio 2019
- python-3.x - DBSCAN homogeneity_score Metrics 显示错误
- sql - (SQFLite) 从 2 个连接表中检索数据并将结果查询转换为列表
- php - 对 WP 查询结果进行排序
- macos - PAM 是在 MacOS 上对用户进行身份验证的合适方法吗
- python - 为什么我的生成对抗网络在训练时总是内存不足?
- swift - 使用复选标记附件发出选择行
- html - 可以在粘贴事件中检测剪贴板数据,但不能在剪切或复制事件中检测
- java - 如何修复循环以获取我传递的值作为参数?