2016-10-04 4 views
1

을 작동시킬 수 장고 관리 목록에있는 대형 데이터베이스 테이블 쿼리의 성능 향상이 조각을 발견 할 수 없습니다 사용하는 경우빠른 장고 관리자 매기기 :이 장고 조각이

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

그것에 대해 몇 가지 문제가 있습니다를 로 이름을

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

특히, _count 요구 사항 : 이미 여기 내 앞의 질문에서 설명 장고 1.10와 그 countquery_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 발로 차고 비명되지 않음) 우리는 장고 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 원래 조각에 사용되는 광범위한 캐싱 코드가 더 이상 필요. 완전성을 위해, 이것은 관련 섹션이 인 모양입니다.

@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

매력처럼 작동합니다. 감사. Funnily, 나는 기본적으로 동시에 스 니펫의 문제를 발견했습니다. try-except로 인해, 나는 단순히'connection'의 누락 된 import를 알아 차리지 못했습니다. –

+0

네, 저에게는 아주 나쁜 일이었습니다. 자신이 동시 발견을 했더라도 정확한 답변을 표시해 주셔서 감사합니다. – e4c5