我只是很困惑。我正在我的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 %}数据库只会被击中两次(我希望这样做,一次是针对成分,另一次是针对prefetch_related)。
问题解决了:问题似乎已经解决了.我一直试着重新启动测试服务器,突然它停止了对所有成分的查询。不知道发生了什么,但我很高兴它解决了。
发布于 2013-10-21 11:03:39
我发现了问题。Schacki的回答是错误的,与预取相关的只需要两个查询,而不是每个成分一个查询。
我的错误出现在模板的另一个部分,在那里我显示中间模型的属性。
所以我应该做的是:
ingredients = Ingredient.objects.all().order_by('accepted', 'name').prefetch_related('canuseunit_set')而不是:
ingredients = Ingredient.objects.all().order_by('accepted', 'name').prefetch_related('useable_units')发布于 2013-07-30 15:36:38
如果你看一下docs:https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related,它会说
另一方面,prefetch_related对每种关系进行单独的查找,并在Python中进行“连接”
据我所知,这正是你所看到的。
https://stackoverflow.com/questions/17951227
复制相似问题