2011-03-25 2 views
39

나는 다음과 같은 장고 모델 : 원함 (직접 SQL을 작성하지 않고) 가능하다면장고의 검색어 역 외래 키

class Make: 
    name = models.CharField(max_length=200) 

class MakeContent: 
    make = models.ForeignKey(Make) 
    published = models.BooleanField() 

내가 알고 싶습니다 내가 모든 Make가 포함 된 검색어 세트를 생성하기 위해를 s 및 각자의 관련 MakeContent s 여기서 published = True.

+0

질문에 대해 더 구체적으로 알려주시겠습니까? – pyeleven

답변

9

장고는 역 외래 키 검색을위한 select_related() 메소드를 지원하지 않으므로 Python을 떠나지 않고 할 수있는 최선의 방법은 두 가지 데이터베이스 쿼리입니다. 첫 번째는 MakeContents가 published = True 인 모든 Makes를 잡고 두 번째는 published = True 인 모든 MakeContents를 가져 오는 것입니다. 그런 다음 원하는 방식으로 데이터를 반복하고 정렬해야합니다. 다음은이 작업을 수행하는 방법에 대한 좋은 기사입니다 :

http://blog.roseman.org.uk/2010/01/11/django-patterns-part-2-efficient-reverse-lookups/

+18

이 질문에 지금 회신해야한다고 생각하지 마십시오 ... –

+2

prefetch_related() 메서드를 사용하여 언급 한 두 개의 쿼리를 간소화하십시오. –

42

예, 나는 당신이

make = Make.objects.get(pk=1) 
make.make_content_set.filter(published=True) 

아니면

make_ids = MakeContent.objects.filter(published=True).values_list('make_id', flat=True) 
makes = Make.objects.filter(id__in=make_ids) 
+3

내가 틀리지 않으면'.values'를'.values_list'로 대체해야합니다. – exfizik

+1

첫 번째 코드 스 니펫이 작동하지 않습니다. * one * make에 대한 모든 MakeContents를 얻습니다. 여기서 MakeContents for all Makes가 필요합니다. _set은 단일 객체에 대해서는 작동하지만 쿼리 세트에 대해서는 작동하지 않습니다. – knite

+0

'flat = True'를 추가하는 것은 무엇입니까? id는 이미 정의에 따라 고유 할 것이고 고유하다는 것을 다시 확인하면 몇 가지 추가 계산이 필요할 수 있습니다. – pintoch

9

나를위한 코드로 스파이크의 말로 대답을 번역하자 싶은 생각 미래의 시청자. 각 '만들기'는 여러 개의 제로를 가질 수 있습니다 'MakeContent'

아스 커는 적어도 하나의 'MakeContent'누구 = TRUE 출판이, 제이슨 크리스타의 2 조각이 질문에 대한 대답으로 '확인'조회하는 것을 의미하는 경우 .

코드 조각은

makes = Make.objects.select_related().filter(makecontent__published=True).distinct() 

에 해당합니다하지만 아스 커 조회하는 것을 의미하는 경우 ALL 'MakeContent'발표 = 사실, 다음, 위에서 '수'다음

import operator 
make_ids = [m.id for m in makes if 
    reduce(operator.and_, [c.published for c in m.makecontent_set.all()]) 
] 
makes_query = Make.objects.filter(id__in=make_ids) 
으로 '확인'

에는 원하는 쿼리가 들어 있습니다.

4

나는 이것이 매우 오래된 질문이라는 것을 알고 있지만, 나는 대답하고있다. 내 대답은 다른 사람들을 도울 수 있다고 생각합니다. 나는 모델을 다음과 같이 조금 바꿨다. 나는 Django 1.8을 사용했다.

class Make(models.Model): 
    name = models.CharField(max_length=200) 

class MakeContent(models.Model): 
     make = models.ForeignKey(Make, related_name='makecontent') 
     published = models.BooleanField() 

다음 쿼리 세트를 사용했습니다.

Make.objects.filter(makecontent__published=True) 

희망이 있으면 도움이 될 것입니다.