【问题标题】:QuerySet select_related not working when overriding get_queryset methd on generic ListViewQuerySet select_related 在通用 ListView 上覆盖 get_queryset 方法时不起作用
【发布时间】: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


【解决方案1】:

我需要在select_related 方法调用中包含PH 的外键,因为它在get_absolute_url 方法中使用:

    def get_queryset(self):
        return Property.objects.filter(ph=self.kwargs['ph_pk']).select_related('building', 'ph')

感谢您的 cmets

【讨论】:

    猜你喜欢
    • 2015-09-28
    • 2020-05-03
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    相关资源
    最近更新 更多