2012-10-20 4 views
0

나는 두 가지 모델로, 프로젝트 및 액션이 있습니다장고 쿼리

class Project(models.Model): 
    name = models.CharField("Project Name", max_length=200, unique = True) 

class Action(models.Model): 
    name = models.CharField("Action Name", max_length=200) 
    project = models.ForeignKey(Project, blank=True, null=True, verbose_name="Project") 
    notes = models.TextField("Notes", blank=True) 
    complete = models.BooleanField(default=False, verbose_name="Complete?") 
    status = models.IntegerField("Action Status", choices = STATUS, default=0) 

내가 반환하는 쿼리를 필요로하는 모든 프로젝트는있는 상태로 아무런 조치가없는 < 2.

Project.objects.filter(action__status__gt = 1) 

을하지만이 모든 프로젝트 각 프로젝트에서, 상태 2 일부 작업 및 상태와 일부 작업이 있기 때문에 또한 2보다 작은,이 연구를 반환

나는 시도 결과 쿼리에서 프로젝트가 중단되었습니다. 나의 현재 솔루션은 다음과 같습니다 :

Project.objects.filter(action__status__gt =1).exclude(action__status__lt =2).annotate() 

이 반복 결과를 축소하고 1보다 큰 동작 만 동작 상태를 보여줍니다하지만이 같은 쿼리를 구성하는 올바른 방법인가? 작업 상태가 1보다 큰 프로젝트를 반환하거나 작업이없는 프로젝트를 원한다면 어떻게해야합니까?

답변

0

귀하의 요구 사항을 오해했을 수도 있지만 특수 효과를 사용하면 그럴 수 있다고 생각합니다. 는 SQL 생성

Project.objects.annotate(m = Min('action__status')).filter(Q(m = None) | Q(m__gt = 1))

은 다음과 같습니다 꽤 자기 설명이다

SELECT 
    "testapp_project"."id", "testapp_project"."name", 
    MIN("testapp_action"."status") AS "m" 
FROM "testapp_project" 
LEFT OUTER JOIN "testapp_action" ON ("testapp_project"."id" = "testapp_action"."project_id") 
GROUP BY "testapp_project"."id", "testapp_project"."name" 
HAVING(
     MIN("testapp_action"."status") IS NULL 
    OR MIN("testapp_action"."status") > 1 
) 

.

0

장고의 ORM은이를 표현할 수 없습니다. 이 작업을 수행하려면 원시 쿼리를 사용해야합니다.

+0

감사합니다. 아마 그것이 사실 일 것 같은 이유를 알 수 있습니다. 이 원시 쿼리를 작성하는 방법에 대한 조언이 있습니까? –