为啥 Django 在更改列表视图页面中进行不必要的 SQL 查询?

Posted

技术标签:

【中文标题】为啥 Django 在更改列表视图页面中进行不必要的 SQL 查询?【英文标题】:Why does Django make unnecessary SQL queries in Change List View Page?为什么 Django 在更改列表视图页面中进行不必要的 SQL 查询? 【发布时间】:2012-11-22 00:30:00 【问题描述】:

我有一个 Django 模型说,

class Student(models.Model):
    prefix           = models.CharField(max_length = 10, blank = True, null = True,)
    suffix           = models.CharField(max_length = 10, blank = True, null = True,)
    fullname         = models.CharField(max_length = 100, null = False,)
    fname            = models.CharField(max_length = 100, verbose_name = u'First Name', blank = True, null = True,)
    midname          = models.CharField(max_length = 100, verbose_name = u'Middle Name', blank = True, null = True,)
    lname            = models.CharField(max_length = 50, verbose_name = u'Last Name', default = ' ')
    department       = models.ForeignKey('Department')

在列表显示中(admin.py)

    list_display = ('fname', 'midname', 'lname', 'prefix', 'suffix',)

为此,包含上述字段的简单选择查询就足够了,但是当有 FK 时,Django 使用内连接以复杂的方式进行 SQL 查询。例如,

通常django必须实现

     SELECT 'fname', 'midname', 'lname', 'prefix', 'suffix' FROM student LIMIT 0,100;

但是 Django 对所有可能的字段进行 SELECT 查询。

SELECT student.prefix.student.suffix .... deparment.id ,depatment.name ..... 
INNER JOIN department ON deparment.id = student.id ........ LIMIT 100

有人可以就为什么需要不必要的查询给出合理的解释吗?

【问题讨论】:

我认为是因为简单和无处不在?您可以通过手动覆盖ModelAdmin.queryset 或通过一些包装代码轻松实现。 【参考方案1】:

Django 不会预见开发人员将选择哪些字段。因此,它将所有字段提供给管理模板,包括所有相关表中的字段。如果需要,开发人员可以覆盖管理模板。 queryset() 将提供发送自定义 sql 语句的能力。

希望问题得到解答。

【讨论】:

但我觉得这不是 Django 的有效方式【参考方案2】:

我的坏! 我正在使用 list_filter = ['department__name']

所以它是 INNER JOIN WITH 部门。我现在删除了它,它向我展示了优化的查询

DJANGO 摇滚

【讨论】:

以上是关于为啥 Django 在更改列表视图页面中进行不必要的 SQL 查询?的主要内容,如果未能解决你的问题,请参考以下文章

Django-admin:如何在记录更改列表中显示指向对象信息页面的链接而不是编辑表单?

Django 在基于类的视图中处理多个表单

通过 jQuery 订购 django 更改列表页面?

django 管理界面 - 如何在更改列表视图中折叠/展开对象详细信息?

Django将硬编码的href链接添加到管理模型的表单视图页面

Django - 分页和排序列表