2017-01-10 8 views
2

다음 모델을 가지고 있습니다.Django - select_related()로 쿼리 최적화

class Car(models.Model): 
    owner = models.ForeignKey('Driver') 

class Country(models.Model) 
    name = models.CharField(max_length=255) 

class Driver(models.Model): 
    name = models.CharField(max_length=255) 
    age = models.IntegerField() 
    country = models.ForeignKey('Country') 

자동차를 소유 한 운전자의 이름을 선택하고 싶습니다.

Car.objects.all().values('owner__name') 

내가이 각 개체에 대해 가입 방지하기 위해, select_related() 메소드를 사용해야합니까, 아니면 값을 암시하기 때문에() 메소드 중복? 같은 방법으로
Car.objects.all().select_related('owner').values('owner__name') 

, 내가 원하는,이 시간, 운전자가 자동차를 소유하는 국가의 이름. 어느 것이 최고입니까? 당신의 예에서 .all()

Car.objects.all().values('owner__country__name') 
Car.objects.all().select_related('owner', 'country').values('owner__country__name') 
Car.objects.all().select_related('owner__country').values('owner__country__name') 
+0

당신이'Driver.objects.filter을한다고 가정 마지막 부분 (car__isnull = 거짓, ...)'하지만 질문 조금 넓어서 암시 적 조인에 관한 첫 번째 질문으로 제한해야합니다 – Sayse

+1

감사합니다. select_related()를 사용하여 범위를 줄이기 위해 질문을 편집합니다. – srjjio

답변

2

첫째, 모든 발생을 삭제할 수 있습니다; 관리자 (.objects)는 이미 .delete()을 제외한 QuerySet의 거의 모든 메소드를 가지고 있습니다.

.select_related은 궁극적 인 쿼리가 모델 인스턴스을 반환 할 때만 유용합니다. 그런 다음 각 인스턴스의 모든 외래 키가 미리로드됩니다.

그러나 .values을 사용하는 경우 사전을 가져오고 사전로드 할 외부 키 속성이 없습니다. 따라서이 경우에는 사용해서는 안됩니다.

.values('owner__name') 장고는 이미 소유자와 자동차에 가입해야한다는 것을 알고 있으므로 추가 쿼리가 수행되지 않습니다. 당신이 국가 원하는 마지막에

, 그래서 사용 Country.objects :

Country.objects.filter(driver__car__isnull=False).values('name') 
+0

의견을 보내 주셔서 감사합니다. 그러나 dict를 사용해도 Django는 각 요소를 반복하는 것으로 상상할 수 있습니다. 데이터베이스에서 새로운 결합 쿼리를 만들 수 있습니다. 이것이 왜 내가 선택한 선택이이 경우 유용하지 않은지 확인하고자하는 이유입니다. – srjjio