Faster Django Admin Paginator:无法使此 Django 代码片段正常工作
Faster Django Admin Paginator: Cannot get this Django snippet to work
我在 Django 管理列表中找到了用于提高大型数据库 table 查询性能的代码段:
https://djangosnippets.org/snippets/2593/
将它与 Django 1.10 一起使用时会出现一些问题,这些问题已在我之前的问题中讨论过:
特别是,_count
需要重命名为 count
,query_set
需要重命名为 queryset
。这是该片段相关部分的简短版本:
from django.core.paginator import Paginator
from django.core.cache import cache
class FasterAdminPaginator(Paginator):
def _get_count(self):
if self.count is None:
try:
key = "adm:{0}:count".format( hash(self.object_list.query.__str__()) )
self.count = cache.get(key, -1);
if self.count == -1 :
if not self.object_list.query.where:
# estimates COUNT: https://djangosnippets.org/snippets/2593/
cursor = connection.cursor()
cursor.execute("SELECT reltuples FROM pg_class WHERE relname = %s",
[self.object_list.query.model._meta.db_table])
self.count = int(cursor.fetchone()[0])
else :
self.count = self.object_list.count()
cache.set(key, self.count, 3600)
except:
# AttributeError if object_list has no count() method.
self.count = len(self.object_list)
return self.count
count = property(_get_count)
问题是,我仍然无法让它工作。当前错误日志摘录:
maximum recursion depth exceeded while calling a Python object
...
result_count = paginator.count
...
if self.count is None:
不知道如何让代码段正常工作。
我认为我们可以像这样将分页器拖到 django 1.10 世界中(希望不要踢和尖叫):
from django.core.paginator import Paginator
from django.core.cache import cache
from django.utils.functional import cached_property
from django.db import connection
class FasterAdminPaginator(Paginator):
@cached_property
def count(self):
try:
if not self.object_list.query.where:
# estimates COUNT: https://djangosnippets.org/snippets/2593/
cursor = connection.cursor()
cursor.execute("SELECT reltuples FROM pg_class WHERE relname = %s",
[self.object_list.query.model._meta.db_table])
print 'Using the reltuples'
ret = int(cursor.fetchone()[0])
else :
return self.object_list.count()
except :
import traceback
traceback.print_exc()
# AttributeError if object_list has no count() method.
return len(self.object_list)
他cached_property the extensive caching code used in the original snippets are no longer needed. For completeness, this is what the relevent section of django.core.paginator.Paginator看起来像
@cached_property
def count(self):
"""
Returns the total number of objects, across all pages.
"""
try:
return self.object_list.count()
except (AttributeError, TypeError):
# AttributeError if object_list has no count() method.
# TypeError if object_list.count() requires arguments
# (i.e. is of type list).
return len(self.object_list)
我在 Django 管理列表中找到了用于提高大型数据库 table 查询性能的代码段:
https://djangosnippets.org/snippets/2593/
将它与 Django 1.10 一起使用时会出现一些问题,这些问题已在我之前的问题中讨论过:
特别是,_count
需要重命名为 count
,query_set
需要重命名为 queryset
。这是该片段相关部分的简短版本:
from django.core.paginator import Paginator
from django.core.cache import cache
class FasterAdminPaginator(Paginator):
def _get_count(self):
if self.count is None:
try:
key = "adm:{0}:count".format( hash(self.object_list.query.__str__()) )
self.count = cache.get(key, -1);
if self.count == -1 :
if not self.object_list.query.where:
# estimates COUNT: https://djangosnippets.org/snippets/2593/
cursor = connection.cursor()
cursor.execute("SELECT reltuples FROM pg_class WHERE relname = %s",
[self.object_list.query.model._meta.db_table])
self.count = int(cursor.fetchone()[0])
else :
self.count = self.object_list.count()
cache.set(key, self.count, 3600)
except:
# AttributeError if object_list has no count() method.
self.count = len(self.object_list)
return self.count
count = property(_get_count)
问题是,我仍然无法让它工作。当前错误日志摘录:
maximum recursion depth exceeded while calling a Python object
...
result_count = paginator.count
...
if self.count is None:
不知道如何让代码段正常工作。
我认为我们可以像这样将分页器拖到 django 1.10 世界中(希望不要踢和尖叫):
from django.core.paginator import Paginator
from django.core.cache import cache
from django.utils.functional import cached_property
from django.db import connection
class FasterAdminPaginator(Paginator):
@cached_property
def count(self):
try:
if not self.object_list.query.where:
# estimates COUNT: https://djangosnippets.org/snippets/2593/
cursor = connection.cursor()
cursor.execute("SELECT reltuples FROM pg_class WHERE relname = %s",
[self.object_list.query.model._meta.db_table])
print 'Using the reltuples'
ret = int(cursor.fetchone()[0])
else :
return self.object_list.count()
except :
import traceback
traceback.print_exc()
# AttributeError if object_list has no count() method.
return len(self.object_list)
他cached_property the extensive caching code used in the original snippets are no longer needed. For completeness, this is what the relevent section of django.core.paginator.Paginator看起来像
@cached_property
def count(self):
"""
Returns the total number of objects, across all pages.
"""
try:
return self.object_list.count()
except (AttributeError, TypeError):
# AttributeError if object_list has no count() method.
# TypeError if object_list.count() requires arguments
# (i.e. is of type list).
return len(self.object_list)