Django管理注释-相关模型的总和字段
我有一个django管理仪表板/列表,它试图跟踪和总结带有注释的queryset的“作业”,我认为它工作不正常。作为表的一部分,我显示了来自相关对象的数据量的计算字段(由带注释的queryset提供) 实际上,它是一个作业列表,跟踪针对计算机设备及其各自存储设备的工作,因此一个作业可以有多个设备,这些设备可以有多个存储设备。设备和存储器都可以包含数据量(就像手机可以拥有内置内存和可移动存储卡一样)。在某些作业中,设备可能是裸硬盘或带有5个HDD的PC塔,因此我正在尝试适应这些场景 models.py:Django管理注释-相关模型的总和字段,django,django-admin,Django,Django Admin,我有一个django管理仪表板/列表,它试图跟踪和总结带有注释的queryset的“作业”,我认为它工作不正常。作为表的一部分,我显示了来自相关对象的数据量的计算字段(由带注释的queryset提供) 实际上,它是一个作业列表,跟踪针对计算机设备及其各自存储设备的工作,因此一个作业可以有多个设备,这些设备可以有多个存储设备。设备和存储器都可以包含数据量(就像手机可以拥有内置内存和可移动存储卡一样)。在某些作业中,设备可能是裸硬盘或带有5个HDD的PC塔,因此我正在尝试适应这些场景 models.
class Job(models.Model):
...
job_number = models.CharField(max_length=50)
job_name = models.CharField(max_length=100)
...
class Device(models.Model):
...
device_number = models.CharField(max_length=50)
job = models.ForeignKey(Job, null=True, on_delete=models.CASCADE)
capacity = models.FloatField(null=True)
...
class Storage(models.Model):
...
storage_number = models.CharField(max_length=50)
device = models.ForeignKey(Device, null=True, on_delete=models.CASCADE)
capacity = models.FloatField(null=True)
...
对于作业的管理模型,我尝试了以下方法,这似乎是可行的,但是当我过滤(例如,基于对作业名称的文本搜索)时,数据量的总数会激增
管理员
class JobAdmin(admin.ModelAdmin)
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset = queryset.annotate(
_device_count=Count("device", distinct=True),
_device_volume=Sum("device__capacity", distinct=True)+Sum("device__storage__capacity", distinct=True)
)
return queryset
def data_label(self,obj):
return obj._device_volume
我注意到,如果我搜索/筛选一个作业名称并获得多个点击,它似乎会将数据总和乘以结果数,但如果我筛选其他字段(使用列表过滤器字段),则不会出现这种情况
谁能看出我错在哪里?谢谢你的建议
Han尽量不要将多个聚合与注释()结合起来,因为(因为使用连接而不是子查询) 那么怎么做呢?使用时,应使用以下方法:
from django.db.models import OuterRef, Subquery, Sum, Count
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset = queryset.annotate(
_device_count=Subquery(
Device.objects.filter(job=OuterRef("pk"))
.values("job")
.annotate(cnt=Count("id"))
.values("cnt")
),
_device_capacity=Subquery(
Device.objects.filter(job=OuterRef("pk"))
.values("job")
.annotate(vol=Sum("capacity"))
.values("vol")
),
_storage_capacity=Subquery(
Storage.objects.filter(device__job=OuterRef("pk"))
.values("device__job")
.annotate(vol=Sum("capacity"))
.values("vol")
),
)
return queryset
您可以尝试再做一次注释,以获得
\u设备\u容量
和\u存储\u容量
的总和,但我想在python中求和是很容易的,所以可能不需要麻烦数据库。哇,谢谢,伙计。通过一个具体的、相关的例子来展示这些概念是非常有用的。我是django nuffy,所以我想我会从这些文件中学到很多东西。顺便说一句,它工作完美!我可以看到如何在查询集之外将它们作为函数的一部分求和,但出于兴趣,我应该如何在查询集中组合它们?它应该是这样的:.annotate(\u total\u capacity=F('u device\u capacity')+F('u storage\u capacity'))
,但您可能还需要将其包装在一个