簡體   English   中英

提高 Django 管理列表過濾器查詢的性能

[英]Improving performance of Django admin list filter queries

我正在圍繞 PostgreSQL 數據倉庫應用程序開發 Django 管理包裝器,該應用程序有一些包含數百萬條記錄的表。

沒有任何列表過濾器的管理員list_filters列表頁面會在一秒鍾內加載,但是如果我在管理員的list_filters包含某些列,它的加載速度會非常緩慢,並且可能需要 30 秒到一分鍾的時間來加載。

檢查數據庫,我看到幾個查詢,如:

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

每一個只需要 3-5 秒,但是有十幾個,這些加起來。 所有字段都被編入索引,所以我不知道我還能如何加快它們的速度。 如何提高管理性能? 我將如何插入 Django 的緩存機制來緩存這些列表過濾器的實際查詢?

正如你所觀察到的; 緩慢來自 django 編譯唯一值列表,以便它可以在側邊欄中顯示它們。

在幕后,這需要對數據庫進行全表掃描,當您的表非常大時,這會很昂貴。 如果您將此字段用作 list_filter; 很有可能唯一值的數量很少,並且您可以自己更有效地生成唯一值列表(假設您知道這些值的來源)。 為此,您可以定義自定義 list_filter。

來自文檔(為簡潔起見而濃縮):

list_filter 應該是元素的列表或元組,其中每個元素應該是以下類型之一:

  • 字段名稱
  • 從 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,)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM