2017-02-12 2 views
1

У меня есть следующие модели:Джанго 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_related (docs) и prefetch_related (docs) будет делать запрос к базе данных, но это уменьшит количество выполненных вызовов.

Смежные вопросы