关于select_related()缓存

时间:2011-01-27 14:43:25

标签: django django-models

我正在做一个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'),因此>>> ac = ax[0] >>> dir(ac) ...... '_item_cache', ....... >>> dir(ac.item) ...... '_country_cache','_region_cache',....... 无效吗?

在shell中:

{{1}}
谢谢。

2 个答案:

答案 0 :(得分:0)

这应该有效。你能在shell中试试吗?像在视图中一样获取ax查询集,然后使用dir检查第一个成员:

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

您应该看到的一个属性是_item_cache,这是Django缓存ForeignKey查找的方式。同样,如果您执行dir(ac.item),则会看到_region_cache_country_cache的条目。如果没有,请在此处发布结果,希望我们可以进一步调试。

答案 1 :(得分: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]

我没有对此进行测试,但我认为它应该可行。

相关问题