2016-09-16 1 views
0

I持って次のモデル:ジャンゴサブクエリフィルタ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 SQLが似ている生のSQLを使用して、アカウント値を超えるクエリセットドメインで取得したい:

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 
) 

私はジャンゴでこのような何か試してみました:

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

しかし、動作しません、それはDomain.planに関するエラーをスローする、サブクエリの親クエリからそのフィールド値を参照する方法はありますか?このクエリーセットは有効か、別の(より良い)アプローチがありますか?または私は単純に生のSQLを使用する必要があります、この場合、どのようなオプションが最適ですか?

+0

パレットクエリとは何ですか? – e4c5

+0

残念ながら私は**親**クエリー – Peter

答えて

1

あなたはDjangoの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を交換してください。これら2つは指定されていない場合のデフォルトにすぎません。

更新 非常に複雑なクエリの場合、カーソルを使用して実際のSQLを実行する方がよい場合があります。 Django ORMは通常は十分ですが、必要に応じて十分ではありません。 docsをご覧ください。

+0

答えてくれてありがとうございました。実際にはメールボックスにはメールボックスの計画がないので、mailbox_countを次のように設定する必要があります。あなたのコードは動作していない、あなたのコードを取っている私は、その部分を次のように変更するとうまくいくと思う: 'Mailbox.objects.filter(domain = DomainFromParentQuery).count()'しかし、 'DomainFromParentQuery'またはその可能性がある場合でも – Peter

+0

ああ申し訳ありません。私は誤って読んで、メールボックスには「計画」への外字があると思った。ドメインにfkがあるので、 'plan__mailbox_set__id'の代わりに' mailbox_set__id'を使用してください。私は自分の投稿を編集しました。 –

+0

さて、もう一度更新をお寄せいただき、ありがとうございます。クエリは正常に実行されますが、未加工SQLと同じ結果が得られていないので、合計とカウントの間違った値が与えられています。何が起こるかを見つける問題。 – Peter

関連する問題