2009-06-29 72 views
4

應該用select_related緩存entry_set嗎?即使在使用select_related之後,我的數據庫仍然正在接聽電話。相關部分django:select_related with entry_set

class Alias(models.Model): 
    achievements = models.ManyToManyField('Achievement', through='Achiever') 

    def points(self) : 
     points = 0 
     for a in self.achiever_set.all() : 
      points += a.achievement.points * a.count 
     return points 

class Achievement(models.Model): 
    name = models.CharField(max_length=100) 
    points = models.IntegerField(default=1) 

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

aliases = Alias.objects.all().select_related() 
for alias in aliases : 
    print "points : %s" % alias.points() 
    for a in alias.achiever_set.all()[:5] : 
     print "%s x %d" % (a.achievement.name, a.count) 

而且我在開始時看到一個很大的連接查詢,然後在每個成就中看到一個大的連接查詢。既用於點和名稱查找。

這是一個錯誤,還是我做錯了什麼?

回答

4

Select_related()不適用於許多方面。目前,這是沒有計劃的,但可能是未來的功能。請參閱http://code.djangoproject.com/ticket/6432

在這種情況下,如果您想進行單個查詢,您有兩個選項 1)製作自己的SQL,可能不會很快或很快。 2)您也可以使用外鍵在模型上查詢。在這種情況下,您將能夠使用select_related。你stil將無法訪問modelname_set,但是通過一些格式,你可以在單個查詢中查看你需要的數據。這些選項都不是理想的選擇,但您可以以相近的速度工作。

+0

無賴。你會如何推薦我做這個查詢? SQL手動? – 2009-06-29 20:57:46

0

在Django的1.3可以使用Queryset.values(),並做一些事情,如:

Alias.objects[.filter().exclude() etc.].values('achievements__name', 'achievement__points') 

只有drwaback是,你QuerySetList,而不是查詢集。但是,這可以通過將所有必要的字段值將()簡單地克服 - 你必須改變你的看法;)

這樣可以節省你的查詢數多申...

詳細信息可以在這裏找到在Django文檔: http://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values