2016-10-04 8 views
1

を動作させることはできません私は、Djangoの管理者リストに大規模なデータベーステーブルのクエリのパフォーマンスを向上させるため、このスニペットを見つけました:高速化Djangoの管理ページネータは:このDjangoのスニペットは

https://djangosnippets.org/snippets/2593/

を使用している場合、それについていくつかの問題があります。に改名へ

How to speed up Django's admin pages with PostgreSQL count estimates?

特に、_countニーズ:すでにここで私の前の質問で説明されているDjangoの1.10、とのこと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: 

スニペットの仕組みを理解できません。

答えて

2

は、私はこのような(hopefullly蹴ると叫んではない)私たちはDjangoの1.10世界にそのページネータをドラッグすることができると思いません:cached_property

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) 

Thaknsオリジナルのスニペットで使用される大規模なキャッシュコードが不要になりました。完全性のために、これは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) 
+0

魅力のように動作します。ありがとう。楽しく、私は基本的に同時にスニペットの問題を発見しました。 try-exceptのために、私は単に 'connection'の欠落したインポートに気付かなかっただけです。 –

+0

はい、それはかなり悪いことでした。自分で同時発見を行ったにもかかわらず、答えを正しいとマークしてくれてありがとう – e4c5

関連する問題