2017-02-12 75 views
1

我有以下型号:Django的jeft连接查询

class TestCaseStatus(models.Model): 
    name = models.CharField(default='n/a', max_length=50) 
    def __str__(self): 
     return self.name 


class TestCase(models.Model): 
    id = models.CharField(unique=True, max_length=100, primary_key=True) 
    name = models.CharField(default='n/a', max_length=200) 

    def __str__(self): 
     return self.name 


class TestRun(models.Model): 
    test_id = models.ForeignKey(TestCase) 
    run_id = models.CharField(max_length=100, default='0') 
    datetime = models.DateTimeField() 
    status = models.ForeignKey(TestCaseStatus) 
    messages = models.CharField(default='n/a', max_length=500) 

    def __str__(self): 
     return self.run_id, self.test_id, self.status 

我想执行下面的SQL查询:

select a.test_id_id, a.status_id, b.status_id 
from runscompare_testrun as a 
left join runscompare_testrun as b on a.test_id_id = b.test_id_id 
where a.run_id = 1 and b.run_id=2 

SQL输出:

sql output

我假设有是一个Django的方式来避免使用raw()调用,但我似乎无法找到它。

回答

1

如果我正确理解您的查询,您需要run_id="1"的所有详细信息,其中包含与TestCase相同但run_id="2"相同的任何运行的其他详细信息。

有了这个假设,你可以做这样的事情:

# Start with run_id=1 
a = TestRun.objects.filter(run_id="1").select_related(
     'test_id', 'status').prefetch_related(
     'test_id__testrun_set', 'test_id__testrun_set__status') 

# For each, get related 
for i in a: 
    b = i.test_id.testrun_set.filter(run_id="2") 
    print(i.test_id, i.status, [j.status for j in b]) 

这会不会是一个单一的数据库查询,因为这两个select_relateddocs)和prefetch_relateddocs)将使数据库调用,但它会减少拨打的电话数量。