2010-12-20 9 views
1

관련된 사람의 빈 세트의 모든 객체 가져 오기 :나는 두 가지 모델이있어

class Content(models.Model): 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField(db_index=True) 
    content_object = generic.GenericForeignKey() 
    show = models.BooleanField(default=False) 

class Foo(models.Model): 
    rel = generic.GenericRelation(Content) 

을 그리고 show==True가 있거나 그 케이 (하나가 될 것이다) 관련 콘텐츠 객체의 모든 푸 방법을 얻으려면 관련된 객체가 전혀 없습니다.

Foo.objects.filter(Q(rel__show=True) | Q(rel__hasnone=True)) 

그러나 물론 장고에 hasnone처럼 아무것도 없다 : 뭔가있다.

내가 수행 할 수있는 다른 방법이 있습니까 (불행히도 집계가 일반 관계에서 작동하지 않고 항목을 계산할 수 없음).

+0

아래의 답을 보았습니다. 그러나 더 간단한 생각이 있습니다. 관련 세트를 반복하고 관련 레코드가있는 모든 개체를 목록에 추가합니다. 그런 다음 모델을 다시 반복하고 목록에있는 모든 레코드를 건너 뜁니다. 이것은 더 느리지 만, 파이썬과 Django ORM을 전적으로 사용하는 이점이 있습니다. –

답변

1

좋아, 나는 우리 중 일부 (불행히도 나)를 만족시킬 수있는 대답을했다고 생각한다.

내가 필요로 무엇 LEFT OUTER 장고 (INNER 사람 모두가 사용자에 의해 선언 조인) 같은 것을 지원하지 않는 가입 : 두 모델은 foobar 응용 프로그램에 있고 CTYPE는 것을 나는 가정

SELECT *, `foobar_bar`.`show` AS `show` FROM `foobar_foo` LEFT OUTER JOIN `foobar_bar` 
    ON (`foobar_foo`.`id` = `foobar_bar`.`object_id` and 
     ctype = `foobar_bar`.`content_type_id`) 
    WHERE show=TRUE OR show=NULL 

을 model Foo의 content_type입니다. 나는 그런 질문을 할 수있는 방법을 발견하지 않았습니다하지만 우리는 같은 것을 수행 할 수 있습니다

SELECT *, `foobar_bar`.`show` AS `show` FROM `foobar_foo` LEFT OUTER JOIN `foobar_bar` 
    ON (`foobar_foo`.`id` = `foobar_bar`.`object_id` 
    WHERE (show=TRUE OR show=NULL) AND ctype = `foobar_bar`.`content_type_id` 

그것은 (단지 객체의 ID에 내놓고 다른 CTYPE와 튜플에 참여할 수) 독점적 인 만족은 아니지만 여전히 유용합니다. 이러한 쿼리를 수행하는 방법은 link text입니다. 그것은 수있을 것 같은 뭔가 :

qs = Foo.objects.all() 

qs.query.join((None, 'foobar_foo', None, None)) 
qs.query.join(('foobar_foo', 'foobar_bar', 'id', 'object_id'), promote=True) 
foos. 
qs = qs.extra(select = {'show': 'foobar_bar.show',}, 
       where = "(show=TRUE OR show=NULL) AND ctype = `foobar_bar`.`content_type_id`") 

일반적으로 사용 query.join((,), promote=True)

가 LEFT QUERY 대신 INNER 조인,하지만 우리는 너무 적은 완전히 그 문제 여전히 유용한를 해결하는 것입니다 인수에 하나를 통과 할 수 우리를 가져옵니다.