Skip to main content
 首页 » 编程设计

python之如何覆盖 Django 管理列表中的查询集 count() 方法

2024年08月21日31kevingrace

为了避免耗时且昂贵的精确数据库计数查询,我想像这样重写 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 View 。但这涉及到 Django 存储库中的大量重复代码。

请您参考如下方法:

我可能是错的,但是你可以将 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