2016-09-16 2 views
0

나는이 다음 모델 :장고 서브 쿼리 필터 paret 쿼리에 필드에서 값을 사용하여

class Domain(models.Model): 
    name = models.CharField(...) 
    plan = models.ForeignKey(Plan, ....) 

class Plan(models.Model): 
    name = models.CharField(...) 
    num_ex_accounts = models.IntegerField(...) 

class PlanDetails(models.Model): 
    accounts = models.IntegerField() 
    plan = models.ForeignKey(Plan, ....) 

class Mailbox(models.Model): 
    domain = models.ForeignKey(Domain, ...) 

도메인 계획을 가지고, 어떤 계획이 도메인을 사용하여 사서함을 만들에 대한 계정 값이 N 계획의 세부 사항을 가지고, I

domains = Domain.objects.filter(
       Q(
        PlainDetails.objects.filter(plan = Domain.plan).aggregate(Sum('accounts')) 
        <= 
        Mailbox.objects.filter(domain = Domain).count() 
       ) 
      ) 
:

SELECT domain 
FROM domain, plan 
WHERE plan.id = domain.plan_id 
    AND (
    SELECT SUM(accounts) 
    FROM plandetails WHERE plandetails.plan_id=plan.id 
) 
    <= 
    (
    SELECT COUNT(*) 
    FROM mailbox WHERE mailbox.domain_id=domain.id 
) 

내가 이런 장고 뭔가를 시도 :는 SQL과 같은 것입니다 원시 SQL을 사용하여 계정 값을 초과의 검색어 도메인에 싶어

하지만 작동하지 않습니다, 그것은 Domain.plan에 대한 오류가 발생합니다 하위 쿼리에서 상위 쿼리에서 해당 필드 값을 참조하는 방법이 있습니까? 이 queryset이 ​​유효합니까 아니면 다른 (더 나은) 접근법이 있습니까? 또는 단순히 원시 SQL을 사용해야합니다,이 경우 가장 좋은 옵션은 무엇입니까?

+0

무엇이 paret 쿼리입니까? 또한 – e4c5

+0

미안 ** 부모 ** 쿼리 – Peter

답변

1

장고 1.8을 사용하는 경우 더 높은, 다음이 시도 : 당신이 명시 적으로 PlanForeignKey 분야에서 하나를 지정한 경우

Domain.objects.annotate(
    account_sum=Sum('plan__plandetails_set__accounts'), 
    mailbox_count=Count('mailbox_set__id')) 
).filter(
    account_sum__lte=F('mailbox_count') 
) 

적절한 related nameplandetails_setmailbox_set를 교체합니다. 이 둘은 지정되지 않은 경우 기본값입니다.

업데이트 매우 복잡한 쿼리의 경우 커서를 사용하여 실제 SQL을 실행하는 것이 좋습니다. Django ORM은 일반적으로 충분하지만 필요에 따라 충분하지 않을 수 있습니다. docs을 확인하십시오.

+0

의미 감사합니다 귀하의 답변을 주셔서 감사합니다, 사실 사서함은 사서함과 계획을 계획하고 관계가 없으므로 mailbox_count를 (를) 얻으십시오. 당신의 코드가 작동하지 않는다면, 코드를 가져 간다. 나는 그 부분을 다음과 같이 변경하면 작동한다고 생각한다 :'Mailbox_count = Mailbox.objects.filter (domain = DomainFromParentQuery) .count()'그러나'DomainFromParentQuery'를 참조하는 방법을 찾을 수 없다. 또는 그것의 posiable 경우에도 – Peter

+0

아, 미안해. 나는 잘못 읽고 사서함에'계획'에 대한 외래가 있다고 생각했습니다. 도메인에 fk가 있기 때문에'plan__mailbox_set__id' 대신'mailbox_set__id'를 사용하십시오. 내 게시물을 편집했습니다. –

+0

확인을 위해 다시 한 번 감사드립니다. 지금은 쿼리가 정상적으로 실행되지만 원시 SQL과 동일한 결과를 제공하지 않습니다. 합계 및 개수에 잘못된 값이 주어 지므로 올바른 관련 레코드가없는 것 같습니다. 무슨 일이 일어나는지 찾아내는 문제. – Peter