2010-11-27 11 views
1

あなたには、いくつかのモデルがある場合:ジャンゴ - 最適化問題

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

class Student(models.Model): 
    age = models.PositiveIntegerField() 
    teacher = models.ForeignKey(Teacher, related_name='students') 

を、あなたはこのようにそれを使用します。

>>> student = Student.objects.get(pk=1) 
>>> student.teacher.name # This hits the database 
'Some Teacher' 
>>> student.teacher.name # This doesn't (``teacher`` is cached on the object) 
'Some Teacher' 

素晴らしいです。 Djangoは関連するオブジェクトをキャッシュするので、データベースを悪用することなく再利用できます。あなたはこのようにそれを使用する場合

しかし、:

>>> teacher = Teacher.objects.get(pk=1) 
>>> for student in teacher.students.all(): # This hits the database 
...  print(student.age) 
... 
8 
6 
>>> for student in teacher.students.all(): # This does too (obviously) 
...  print(student.age) 
... 
8 
6 

何のキャッシュや関連するオブジェクトに効率的にアクセス、この方向はありません。

私の質問は、このようにある:あなたができるようには、効率的な方法で後方へのアクセスに関連するオブジェクトに内蔵(または問題のない方法)は上記student.teacherの例では、(キャッシュされた方法)はありますか?

私は何度も同じ関連オブジェクトへのアクセスを必要とする複数の方法でモデルを持っているので、これは、とても12個のクエリを持つべきページを約30

答えて

2

ありISNで終了されたい理由に組み込みの方法ではありません。私はこの問題on my blogについて、逆リレーションシップへのアクセスを最適化するテクニックについて書いています。

+0

優れた:-)この特定の問題についてDjangoの独自のドキュメントへのリンクです!私が新しい問題にぶつかるたびに、あなたは私の前に同じ問題に遭遇しました。皮肉なことにあなたの名前はDanielですが、宮城さんのようです。もう一度感謝します。 – orokusaki

+0

この場合、select_related()は機能しませんか? – jMyles

+0

@Justin - いいえ、 'select_related'は' OneToOne'関係でしか動作せず、Django 1.2 +のみで動作します。 – orokusaki

1

orokusaki、

は、あなただけのpython変数

students = teacher.students.all() 

としてクエリセットをキャッシュし、その後、ちょうどループのために、あなたの中に学生を使用する必要があります。

は以下

http://docs.djangoproject.com/en/1.1/topics/db/optimization/#understand-cached-attributes

+0

(素晴らしい名前、第一に) - ありがとう。問題は同じリクエスト中に複数のコントロールの場所でクエリが実行されているということです。その答えは実際の関連モデルでキャッシュされたバージョンを作成する答えでした(例えば、 '' foo_teacher._cache_students = teacher.students.all() '' <簡略化されたバージョンです。 – orokusaki

関連する問題