Django中带有注释的复杂查询

时间:2011-06-22 10:36:19

标签: django django-models

我必须上课

class JobTitle(models.Model):
    name = models.CharField(max_length=500,null=False,blank=False)


class Employer(models.Model):
     name = models.CharField(max_length=500,null=False,blank=False)
     jobtitle = models.ForeignKey(JobTitle,null=False)
     revenue = models.IntegerField(null=False)

首先,我想获得雇主人数最多的前5个职位,其次我需要评估这五个职位的雇主的平均收入。

我可能会获得前5个职位,如

jtList = JobTitle.objects.filter(isActive=True).annotate(employer_count=Count('employer')).order_by('employer_count')[:5]

我可以查看每个职位和他们的雇主,并将他们的收入总和除以总数,但当然这是一个糟糕而低效的解决方案。

我怎样才能有效地在django中实现这样的操作?

谢谢

JobTitle.objects.annotate(jobtitle_count=Count('jobtitle')).order_by('-jobtitle_count')[:5]

1 个答案:

答案 0 :(得分:2)

以相同货币汇总收入

如果所有收入数字都使用相同的货币,则可以使用annotateAvg执行此操作。

job_titles = JobTitle.objects.filter(isActive=True
                              ).annotate(employer__count=Count('employer'), 
                                         average_revenue=Avg('employer__revenue'),
                              ).order_by('employer__count')[:5]

以不同货币汇总收入

在你提到的评论中,你想转换英镑和欧元的收入,然后用美元汇总。我恐怕没有一个优雅的解决方案。

一种方法是使用values()来获取每种货币的总和:

# look at the employers in the top job titles
employers = Employer.objects.filter(job_title=job_titles)
currency_totals = employers.values('job_title', 'currency', Count('revenue'), Sum('revenue'))

这将返回ValuesQuerySet,例如

[{'job_title':1, 'currency': 'GBP', 'revenue__sum': 20.0, 'revenue__count': 1},
 {'job_title':1, 'currency': 'EUR', 'revenue__sum': 35.0, 'revenue__count': 2},
 {'job_title':2, 'currency': 'USD', 'revenue__sum': 50.0, 'revenue__count': 1},
 ...
]

然后,您可以在视图中循环显示结果,将每个revenue__sum转换为USD并添加到该职位的运行总计。

这样,您只需要一个查询即可获得给定job_titles组的收入总和。但是,因为我们在视图中处理结果,所以您无法通过收入计算来过滤数据库,例如“告诉我相同收入超过1000美元的职称”。

我有兴趣看到任何其他方法 - 我们让客户以英镑,欧元和美元付款,所以我们需要生成类似的报告。