我有一个简单应用的以下模型:
class App(models.Model):
name = models.CharField(max_length=60)
class TestCase(models.Model):
title = models.CharField(max_length=500)
app = models.ForeignKey('apps.App', blank=True)
class Run(models.Model):
timestamp = models.DateTimeField()
value = models.FloatField()
test_case = models.ForeignKey(TestCase)
例如,我想计算特定运行中已执行和完整的案例:
>>> # r is instance of Run
>>> cases_ids = r.values('test_case').distinct()
>>> executed_cases = TestCase.objects.filter(pk__in=cases_ids)
>>> executed_cases_stat = executed_cases.values('app__name').annotate(dcound=Count('app__name'))
[{'executed_cases': 1, 'app__name': u'App1'}, {'executed_cases': 3, 'app__name': u'App2'}]
>>> all_cases_stat = TestCase.objects.all().values('app__name').annotate(total_cases='app__name')
[{'total_cases': 5, 'app__name': u'App1'}, {'total_cases': 7, 'app__name': u'App2'}, {'total_cases': 12, 'app__name': u'App3'}]
>>>
>>> # I want to get this result:
[{'executed_cases': 1, 'total_cases': 5, 'app__name': u'App1'}, {'executed_cases': 3, 'total_cases': 7, 'app__name': u'App2'}, {'executed_cases': 0, 'total_cases': 12, 'app__name': u'App3'}]
我知道这可能是通过SQL(它可能看起来很难看):
select
simple_app.name
, tc.total_cases
, ce.cases_executed
from apps_app
join (
select count(id) as total_cases, app_id
from simple_testcase
group by app_id) tc
on simple_app.id = tc.app_id
join(
select count(id) as cases_executed, app_id
from simple_testcase
where id in (select test_case_id
from simple_run where run_id = 1)
group by app_id) ce
on apps_app.id = ce.app_id
如果没有原始sql或在python中迭代,有没有办法呢?
答案 0 :(得分:3)
我大多数时候都想用注释做一些看似不可能的事情,我使用extra
(https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.extra)
apps_extra = App.objects.all().extra (select={ 'total_cases': """ select count(id) from simple_testcase where simple_app.id = simple_testcase.app_id """, 'executed_cases': """ # the same with your second nested query """, })
现在apps_extra
将包含App
和total_cases
字段的executed_cases
个对象!
这真的很棒,因为您可以apps_extra
使用Column()
作为django_tables2
的{{1}}来源,在该列上启用排序!