2017-01-28 12 views
0

私は3つのモデルを使用しており、N + 1のクエリを避けたいと考えています。与えられたfooのDjango、N + 1クエリを避ける

class Rule(models.Model): 

    pass 


class RuleConstraint(models.Model): 

    rules = models.ManyToManyField(Rule) 


class Foo(models.Model): 

    rule = models.ForeignKey(Rule, related_name='foos') 

、私は

RuleContraint.objects.filter(rules__foos=foo) 
のような関連RuleConstraintsを得ることができます。質問は、私は私ではなく、単一のfooの foosを持つN + 1クエリの症状を、避けるんか、です。あなたが改善することができ

for foo in foos: 
    rule_constraints = foo.rule.ruleconstraint_set.all() 

すなわち、

for foo in foos: 
    rule_constraints = RuleConstraint.objects.filter(rules__foos=foo) 
+0

'select_related'メソッドを見ましたか? https://docs.djangoproject.com/en/1.10/ref/models/querysets/#select-related – gpichot

答えて

1

よりもやっての良い方法は、あなたが、その後でクエリセットを反復処理することができますprefetch_related

foos = Foo.objects.prefetch_related('rule__rule_constraint') 

をしたいがありますこれはさらにselect_relatedを使用してruleを取得します。詳細については

foos = Foo.objects.select_related('rule').prefetch_related('rule__rule_constraint') 

the prefetch related docsを参照してください - あなたのモデルは、例のものと非常に似ています。