2011-01-27 76 views
3

我正在做一個select_related()查詢集以防止不必要的匹配數據庫。 在我的模型,我有:關於select_related()緩存

class Item(models.Model) 
    user = models.ForeignKey(User, related_name='items') 
    name = models.CharField(max_length=255) 
    region = models.ForeignKey(Region, null = True, blank = True) #django-cities 
    country = models.ForeignKey(Country, null = True, blank = True) #django-cities 

    def get_ubicacion_name(self): 
     if self.region: 
      return self.region 
     else: 
      return self.country 

class Activity(models.Model) 
    date = models.DateField() 
    item = models.ForeignKey(Item, related_name='items') 

筆者認爲:

ax = Activity.objects.select_related('item','item__region','item__country').all()[:40] 

在我的模板:

{% for a in ax %} 
    {{ a.date }} - {{ a.get_ubicacion_name }} 
{% endfor %} 

調試工具欄顯示43 queries in 53.87ms因爲打self.country所以select_related('item','item_region','item_country')不工作對於這個def?

在外殼:

>>> ac = ax[0] 
>>> dir(ac) 
...... '_item_cache', ....... 
>>> dir(ac.item) 
...... '_country_cache','_region_cache',....... 

謝謝。

+0

你試過用select_related()嗎?參數的要點是限制查詢所遵循的FK,但只有一個可以遵循,所以無關緊要。此外,您不必告訴它遵循進一步的FK關係(地區和國家),因爲select_related將盡可能自動跟蹤FK。我甚至不確定select_related是否適用於__「follow」語法。 – 2011-01-27 17:16:13

+3

@Alex Kuhl:不,OP的語法是正確的:select_related不會自動遵循'null = True'的關係,這就是區域和國家FK的情況。 – 2011-01-27 17:30:21

回答

0

這應該工作。你可以在殼裏試試嗎?獲取ax查詢集,你在視圖中做的,然後用dir檢查第一個成員:

>>> ac = ax[0] 
>>> dir(ac) 

一個你應該看到的屬性是_item_cache,這是Django的緩存ForeignKey的查找方式。同樣,如果你做dir(ac.item)你應該看到_region_cache_country_cache的條目。如果沒有,在這裏發佈結果,希望我們可以進一步調試。

0

我認爲這個問題是,城市也關係到地區和國家:

class City(models.Model): 
# snip 
region = models.ForeignKey(Region) 
# snip 

def __unicode__(self): 
    return "%s, %s" % (self.name, self.region) 

,當你調用get_ubicacion_name()如果該項目有關聯的城市則City.__unicode__()方法被調用產生至少一個爲每個項目添加新的查詢(查找區域)。

我會改變你的select_related如下:

ax = Activity.objects.select_related(
    'item','item__region__city__country','item__country' 
).all()[:40] 

我沒有測試過這一點,但我認爲它應該工作。