2009-09-06 25 views
14

ich habe:Django: select_related mit ManyToManyField

class Award(models.Model) : 
    name = models.CharField(max_length=100, db_index=True) 

class Alias(models.Model) : 
    awards = models.ManyToManyField('Award', through='Achiever') 

class Achiever(models.Model): 
    award = models.ForeignKey(Award) 
    alias = models.ForeignKey(Alias) 
    count = models.IntegerField(default=1) 

Wie kann ich eine Alias haben, die seine achiever_set und awards alle vorbelegt hat?

>>> db.reset_queries() 
>>> Alias.objects.filter(id="450867").select_related("achiever_set__award").get().achiever_set.all()[0].award.name 
u'Perma-Peddle' 
>>> len(db.connection.queries) 
3 
>>> db.reset_queries() 
>>> Alias.objects.filter(id="450867").select_related("awards").get().awards.all()[0].name 
u'Dwarfageddon (10 player)' 
>>> len(db.connection.queries) 
2 

Ich werde viel Zugriff auf die Auszeichnung müssen, die ein Alias ​​bereits bekommen hat (sowohl der Zwischentisch und die Auszeichnungen selbst). Wie kann ich all diese Dinge chargen?

Antwort

21

Django Versionen 1.4 und höher haben prefetch_related für diesen Zweck.

Die Methode prefetch_related ähnelt select_related, führt jedoch keine Datenbankverbindung durch. Stattdessen führt es zusätzliche Datenbankabfragen aus und führt den Beitritt in Python durch.

3

Wenn Sie nicht auf Django 1.4 sind, gibt es auch die Bibliothek django-batch-select, die im Prinzip genauso funktioniert wie prefetch_related.

Verwandte Themen