python - 提高 Django 管理列表过滤器查询的性能

标签 python django django-admin

我正在围绕 PostgreSQL 数据仓库应用程序开发 Django 管理包装器,该应用程序有一些包含数百万条记录的表。

没有任何列表过滤器的管理员更改列表页面会在一秒钟内加载,但是如果我在管理员的 list_filters 中包含某些列,它加载非常缓慢,加载可能需要 30 秒到 1 分钟。

检查数据库,我看到了几个查询,如:

SELECT DISTINCT "warehouse_data"."filter_field1" FROM "warehouse_data" ORDER BY "warehouse_data"."filter_field1" ASC;

每一个只需要 3-5 秒,但是有十几个,这些加起来。所有字段都被编入索引,所以我不知道我还能如何加快它们的速度。如何提高管理性能?我将如何插入 Django 的缓存机制来缓存这些列表过滤器的实际查询?

最佳答案

正如你所观察到的;缓慢来自 django 编译唯一值列表,以便它可以在侧边栏中显示它们。

在幕后,这需要对数据库进行全表扫描,当您的表非常大时,这会很昂贵。如果您将此字段用作 list_filter;很有可能唯一值的数量很少,并且您可以自己更有效地生成唯一值列表(假设您知道这些值的来源)。为此,您可以定义自定义 list_filter。

来自 the docs (为简洁而浓缩):

list_filter should be a list or tuple of elements, where each element should be of one of the following types:

  • a field name
  • a class inheriting from django.contrib.admin.SimpleListFilter

from datetime import date
from django.contrib import admin
from django.utils.translation import gettext_lazy as _

class DecadeBornListFilter(admin.SimpleListFilter):
    title = _('decade born')
    parameter_name = 'decade'

    def lookups(self, request, model_admin):
        return (
            ('80s', _('in the eighties')),
            ('90s', _('in the nineties')),
        )

    def queryset(self, request, queryset):
        # Compare the requested value (either '80s' or '90s')
        # to decide how to filter the queryset.
        if self.value() == '80s':
            return queryset.filter(birthday__gte=date(1980, 1, 1),
                                    birthday__lte=date(1989, 12, 31))
        if self.value() == '90s':
            return queryset.filter(birthday__gte=date(1990, 1, 1),
                                    birthday__lte=date(1999, 12, 31))

class PersonAdmin(admin.ModelAdmin):
    list_filter = (DecadeBornListFilter,)

关于python - 提高 Django 管理列表过滤器查询的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22080469/

相关文章:

python - Selenium 测试 - 测试单击按钮是否打开正确的项目

django - 如何从命令行浏览django psql后端

python - 在 Django 管理界面的用户名中允许 "- "字符

django - 编写自定义 Django 小部件的教程?

Django-cms 示例。如何运行它?

Django 作为 S3 代理

python - 在 Python 中使用空格字符作为分隔符将句子分成单词

python - 在 matplotlib 中将 x 轴移动到绘图的顶部

Python jsonschema 无法验证字符串枚举

python - Python 中的 Unicode 全角到标准 ASCII(反之亦然)