为了避免耗时和昂贵的精确数据库计数查询,我想在Django管理类中覆盖count()
方法,如下所示:
from django.contrib import admin
from django.db import connection
class CountProxy:
def __call__(self):
# how to access the queryset `query` here?
query = ...
try:
if not query.where:
cursor = connection.cursor()
cursor.execute("SELECT reltuples FROM pg_class WHERE relname = %s", [query.model._meta.db_table])
n = int(cursor.fetchone()[0])
if n >= 1000: return n # exact count for small tables
return object_list.count()
except:
# exception for lists
return len(object_list)
return estimated_count
class MyAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(MyAdmin, self).get_queryset(request)
qs.count = CountProxy()
return qs
但是我不知道如何在我的CountProxy
类中访问原始的查询集。有什么想法吗?我知道我可以通过get_changelist
覆盖整个changelist
视图。但是这涉及到大量重复的Django仓库代码。
4条答案
按热度按时间tzdcorbm1#
我可能是错的,但是您可以将
qs
作为CountProxy
的示例属性传递吗?lstz6jyr2#
我以前做过类似的事情,所以我可以帮助你。
我定义了一个自定义的queryset类:
然后定义了一个自定义模型管理器:
然后在我的模型中使用它:
ymdaylpp3#
这就是我在postgres和Django 2.2.x中所做的
最后覆盖你的模型管理器:
h5qlskok4#
如果你想让管理页面在大计数时更快,你可以定义一个模型的 Package 器。Admin作为queryset返回一个queryset,而不是正常的计数,只有当结果没有被过滤时才使用一个近似值。这适用于Postgres 12和Django 4.1.7:
你可以这样使用它: