prefetch_related不缓存

时间:2013-07-30 15:28:36

标签: django django-models

我很难过。我正在尝试在我的django应用程序中实现prefect_related的教科书案例,但它根本行不通。以下是相关模型:

class CanUseUnit(models.Model):

  objects = UnitManager()

  ingredient = models.ForeignKey('Ingredient', db_column='ingredient', related_name='useable_units')
  unit = models.ForeignKey('Unit', related_name='used_by', db_column='unit', limit_choices_to=models.Q(parent_unit__exact=None))

请注意,尽管此模型具有自定义管理器,但这是models.Managar的简单子类,只有一个名为get_all_info()的方法,所以我认为这与我的问题没有任何关系:

我正在尝试查询所有成分,并预取其可用单位。这是我的Django查询:

def list_ingredients(request):
  ingredients = Ingredient.objects.all().order_by('accepted', 'name').prefetch_related('useable_units')
  for ingredient in ingredients:
    print(ingredient.useable_units.all())

  return render(request, 'admin/list_ingredients.html', {'ingredients': ingredients})

但Django似乎在每个print语句中都会访问数据库......发生了什么事?

编辑:

从模板调用时,缓存似乎有效。当我在上面的视图中省略print语句时,访问包含以下模板代码的页面:

{% for ingredient in ingredients %}
<tr>
  <td><a href="/ingredients/edit/{{ ingredient.id }}/">{{ ingredient.name }}</a></td>
  <td align="center">{{ ingredient.useable_units.count }}</td>
</tr>

{% endfor %}

数据库只被击中两次(我预计,一次为Ingredients,一次为prefetch_related)。

解决: 好吧,问题似乎已经解决了......我一直在尝试并重新启动测试服务器,突然它停止查询每个成分。不确定发生了什么,但我很高兴它已经解决了。

2 个答案:

答案 0 :(得分:0)

我发现了问题。 Schacki的答案是错误的,预取相关确实只需要2个查询而不是每个成分一个。

我的错误出现在模板的另一部分,我正在显示中间模型的属性。

所以我应该做的是以下内容:

ingredients = Ingredient.objects.all().order_by('accepted', 'name').prefetch_related('canuseunit_set')

而不是:

ingredients = Ingredient.objects.all().order_by('accepted', 'name').prefetch_related('useable_units')

答案 1 :(得分:-2)

如果您查看文档:{​​{3}},则说明

  另一方面,

prefetch_related对每个关系进行单独查找,并在Python中进行“加入”

根据我的理解,这就是你所看到的。