【发布时间】:2017-12-13 15:20:43
【问题描述】:
在泛型ListView 上覆盖get_queryset 方法时,select_related() 方法对queryset 没有任何影响,在模板循环上进行 n+1 次 sql 调用:
models.py:
class Bulding(models.Model):
name = models.Charfield(max_length=100)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('properties:building_detail', args=[str(self.ph.pk), str(self.id)]) ...
class Property(models.Model):
building = models.ForeignKey(Building)
def get_absolute_url(self):
return reverse('properties:property_detail', args=[str(self.ph.pk), str(self.id)])
views.py
class PropertyListView(LoginRequiredMixin, PHViewMixin, ListView):
model = Property
def get_queryset(self):
return super().get_queryset().filter(ph=self.kwargs['some_kw']).select_related('building')
property_list.html:
...
{% for p in object_list %}
<tr>
<td>{{ p.building }}</td><td><a href="{{ p.get_absolute_url }}">{{ p.name }}</a></td>>...</td>
</tr>
{% endfor %}
...
如果我删除 {{p.building}},我会收到 3 个 sql 调用,而现在是 47 个,使用 django-debug-toolbar 检查。
感谢您的帮助。
埃里克
【问题讨论】:
-
您使用 select_related() 方法的目的是什么? select_related() 方法是一种在具有 FK 关系时通过一个查询一次检索所有内容的方法。
-
没错,就是这样,但是在访问 Building 外键时,我在每个 Property 对象的循环上都获得了一个新的 db 调用
-
你可以试试 select_related('building__name') 吗?
-
也不起作用,检查。 Name 不是 Building 的外键。
-
PHViewMixin是否也覆盖get_queryset?
标签: django python-3.x django-views django-queryset