Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django在queryset中获取总计数和按唯一值计数_Python_Django_Django Queryset_Aggregate Functions - Fatal编程技术网

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'))
我认为你在内存中这样做是对的–尽管我觉得在
域上有一对多的关系
回到
软件
它可以单独在查询集中工作