2011-10-30 10 views
2

に多くの複数のオブジェクトを選択します。次のモデルがありますが、多くの

class Schema(models.Model): 
    keys = models.ManyToManyField(Key, through='SchemaHasKey') 
    # ... 

class Key(models.Model): 
    name = models.CharField(max_length=50) 
    # ... 

は私がキーと10の最初のスキーマを選択する必要がありますが、私のやり方が悪いです:

schemas = [] 

for schema in Schema.objects.all().order_by('pk')[:10]: 
    schema.key = schema.keys.all() 
    schemas.append(schema) 

は.select_relatedは()ではありませんうまくいく:

schemas = Schema.objects.select_related().order_by('pk')[:10] 

これは特定の数のSQLクエリで実行できますか?

答えて

2

はここprefetch_related機能が正式に開始されるまで、私はそれを行う可能性がある方法です。

2つのクエリ。

from collections import defaultdict 

schemas = Schema.objects.order_by('pk')[:10] 
key_map = defaultdict(lambda:[]) # always return a list 

# use m2m through table to get all schema-key relationships related to the 10 
# create a list of each `Key` with the Schema ID as the dict key. 
[key_map[through.schema.id].append(through.key) for 
    through in Schema.keys.through.objects.filter(schema__in=schemas)] 

for schema in schemas: 
    schema.keys = key_map[schema.id] 
+0

".append(key_through.key)"にする必要はありませんか?また、スキーマにキーがない場合に、 "key_map [schema.id]"をラップする必要はありませんか? –

+1

@ダン、良い目!一定。 –

+0

もう1つのこと - 私の設定(django 1.1)では、スルースルーはマネージャからではなくdbから引き出されたオブジェクトにのみ設定されているようです。 defaultdictでの改善 –

1

編集:prefetch_relatedはDjango開発版でのみ動作します。

djangos prefetch_relatedの機能を使用できると思います。 ManyToManyフィールドもサポートしています。これは1つのSQLクエリで結合を行いませんが、それは別の方法をスピードアップする可能性があります。

それはこのように使用することができます:

Schema.objects.all().prefetch_related('keys').order_by('pk')[:10] 
+0

.prefetch_related()はまだ動作しません:( – Deadly

+0

は@Deadly私は用事その後、彼らは彼らのドキュメント:)で大きなフォントでそれを書いて検討すべきである、参照してください。 – Lycha

関連する問題