2010-11-27 4 views
1

Wenn Sie einige Modelle:Django - Optimierung Frage

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

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

und verwenden Sie es wie folgt aus:

>>> 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' 

Das ist genial. Django speichert das verwandte Objekt, so dass Sie es erneut verwenden können, ohne Ihre Datenbank missbrauchen zu müssen.

Aber, wenn Sie es wie folgt verwenden:

>>> 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 

Es gibt keinen Cache oder einen effizienten Zugriff auf verwandte Objekte diese Richtung.

Meine Frage ist also: Gibt es eine eingebaute (oder unproblematische Art und Weise), um rückwärts zugangsbezogene Objekte auf effiziente Art und Weise (ein im Cache gespeicherte Weg), wie Sie können in dem student.teacher Beispiel oben?

Der Grund möchte ich dies, weil ich ein Modell mit mehreren Methoden, die Zugriff auf die gleichen Objekte verknüpft und immer brauchen, also eine Seite, die 12 Abfragen endet mit etwa 30.

Antwort

2

haben sollte dort isn 't kein eingebauter Weg. Ich habe über dieses Problem geschrieben on my blog, mit einer Technik, um den Zugriff auf umgekehrte Beziehungen zu optimieren.

+0

ausgezeichnet! Jedes Mal, wenn ich auf ein neues Problem stoße, ist das gleiche Problem schon lange vor mir aufgetreten. Du bist wie mein Mr. Miyagi, obwohl ironisch dein Name Daniel ist :) Danke nochmal. – orokusaki

+0

Funktioniert select_related() in diesem Fall nicht? – jMyles

+0

@Justin - nein, 'select_related' funktioniert nur in umgekehrter Reihenfolge mit' OneToOne' Beziehungen und nur Django 1.2 +. – orokusaki

1

orokusaki,

Sie müssen nur die queryset als Python-Variable für Schleifen in Ihrem

students = teacher.students.all() 

Und dann nur Studenten verwenden zwischenzuspeichern.

Unten ist ein Link zu Djangos eigener Dokumentation zu diesem speziellen Thema :-)

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

+0

(genialer Name, zuerst) - danke. Das Problem besteht eher darin, dass die Abfrage an mehreren Kontrollorten während der gleichen Anfrage ausgeführt wird, aber von derselben Klasse, daher war die Antwort für mich, eine zwischengespeicherte Version auf dem tatsächlich verwandten Modell zu erstellen (zB '' foo_teacher._cache_students = teacher.students.all() '' orokusaki