Python Django在queryset中获取总计数和按唯一值计数
我将Python Django在queryset中获取总计数和按唯一值计数,python,django,django-queryset,aggregate-functions,Python,Django,Django Queryset,Aggregate Functions,我将软件和域的模型粗略地描述为: class Software(models.Model) id = models.BigInteger(primary_key=True, db_index=True, null=False) company = models.ForeignKey('Company') domain = models.ForeignKey('Domain') type = models.CharField(null=False) vend
软件
和域
的模型粗略地描述为:
class Software(models.Model)
id = models.BigInteger(primary_key=True, db_index=True, null=False)
company = models.ForeignKey('Company')
domain = models.ForeignKey('Domain')
type = models.CharField(null=False)
vendor = models.CharField(null=False)
name = models.CharField(null=False)
class Domain(models.Model):
id = models.BigInteger(primary_key=True, db_index=True, null=False)
type = models.CharField()
importance = models.DecimalField(max_digits=11, decimal_places=10, null=False)
我得到了一个软件查询集,其中包括:
qs=Software.objects.filter(company=c)。订购人('vendor')
所需输出应具有聚合的域
重要性,以及每个唯一的软件
的总计数,即
[
{
'type': 'type_1', \
'vendor': 'ajwr', | - unique together
'name': 'nginx', /
'domains': {
'total_count': 4,
'importance_counts': [0.1: 1, 0.5: 2, 0.9: 1] # sum of counts = total_count
},
},
{
...
},
]
我觉得这里的第一步应该是按照域
对类型、供应商、名称
进行分组,这样每个软件
对象都有一个域的列表,而不是一个,但我不确定如何做到这一点。在内存中执行此操作将使其更加容易,但似乎比使用querysets/SQL慢得多。因此,我将这样做:
from django.db.models import Sum
qs = Software.objects.filter(company=c).prefetch_related(
'domain'
).annotate(
total_count=Sum('domain__importance')
).order_by('vendor')
output = []
for obj in qs:
domains = obj.domain.all() # using prefetched domains, no db query
output.append({
# ...
'domains': {
'total_count': obj.total_count,
'importance_counts': [d.importance for d in domains]
}
})
我相信它应该足够快。只有发现不是这样,我才会努力改进。记住“过早优化是万恶之源”这看起来更像是序列化程序的工作(如您所说,在python中执行),但为了确保避免执行许多db查询,您应该使用。prefetch\u related('domain'))
我认为你在内存中这样做是对的–尽管我觉得在域上有一对多的关系
回到软件
它可以单独在查询集中工作