2017-02-12 42 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)將使數據庫調用,但它會減少撥打的電話數量。