如何覆盖 Django 管理列表中的 queryset count() 方法

Sim*_*ger 6 python django admin count

为了避免耗时且昂贵的精确数据库计数查询,我想像这样覆盖count()Django 管理类中的方法:

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
Run Code Online (Sandbox Code Playgroud)

但我不知道如何访问我CountProxy班级中的原始查询集。任何的想法?我知道我可以changelist通过get_changelist. 但这涉及来自 Django 存储库的大量重复代码。

Sha*_*ang 4

我可能是错的,但是你可以qs作为 的实例属性传递吗CountProxy?

class CountProxy:
    def __init__(self, query):
        self.query = query

    def __call__(self):
        # you've already had the query here, do something with self.query

class MyAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = super(MyAdmin, self).get_queryset(request)
        qs.count = CountProxy(qs)
        return qs
Run Code Online (Sandbox Code Playgroud)