我正在做一个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}}谢谢。
答案 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]
我没有对此进行测试,但我认为它应该可行。