2009-12-20 4 views
1

나는이 다음 모델 :캐싱 장고 쿼리 결과

class Territory(models.Model): 
    name = models.CharField(max_length=30) 
    power = models.ForeignKey(Power, null=True, blank=True) 
    is_supply = models.BooleanField() 

class Subregion(models.Model): 
    territory = models.ForeignKey(Territory) 
    subname = models.CharField(max_length=10, blank=True) 
    sr_type = models.CharField(max_length=1, choices=SUBREGION_CHOICES) 
    init_unit = models.BooleanField() 
    borders = models.ManyToManyField("self", null=True, blank=True) 

    def __unicode__(self): 
     if self.subname: 
      return u'%s (%s)' % (self.territory.name, self.subname) 
     else: 
      return u'%s [%s]' % (self.territory.name, self.sr_type) 

문제가 ModelFormSet을 렌더링 할 때, 각 양식이있는 모든 120 Subregions를 포함하는 3 ModelChoiceFields을 가지고 있다는 것입니다, 각 Subregion에 대해 개별 SELECT 쿼리가 생성됩니다. 내 Postgres 로그에 따르면 페이지로드 시간에 눈에 띄는 영향을주는 간단한 3- 폼 formset에 대해 1000 개가 넘는 쿼리가 생성됩니다.

그럼, Subregion.__unicode__()이 원하는 모든 정보를 캐시하는 단일 대형 쿼리를 수행하는 합리적인 방법이 있습니까?

답변

1

select_related()을 사용해 보셨습니까? 이것은 territory.name에 대한 추가 검색을 도와줍니다. select_related()의 기본값은 null = True 인 외래 키를 따르지 않으므로 테두리는 건너 뜁니다. 테두리를 가져와야하는 경우 관련된 객체의 이름을 명시 적으로 시도 할 수 있습니다 (Subregion.objects.select_related('territory', 'borders').all()).

) (앱의 ./manage.py shell에서 스핀을 위해 이것을 가지고 select_related 있는지 확인하는 데 도움이 :

>>> from django import db 
>>> db.reset_queries() 
>>> Subregion.objects.all() 
# ... 
>>> len(db.connection.queries) 
# some big number 
>>> db.reset_queries() 
>>> Subregion.objects.select_related().all() 
# ... 
>>> len(db.connection.queries) 
# a smaller number 
+0

내가 이전에 다음의 모든이의 검색어를 통과, 그와의 검색어를 구성하여 select_related''사용하여 시도했다 'ModelChoiceFields'는'formfield_callback'을 사용합니다. 쿼리 수에 차이가 없습니다. 그러나 위의 코드는 효과가있었습니다 (21 대 1). –

+0

... 내 콜백 함수에서 실수를했기 때문입니다. 예,'select_related'만으로 1136 개의 선택 쿼리에서 56 개로 충분합니다. –

+0

또는 [이 질문에서] (http://stackoverflow.com/questions/9262036/django-unicode-and-fk-is-very-slow)에서 언급 한 바와 같이'select_related()'와 함께 사용자 정의 관리자를 사용하십시오. [Managers의 문서] (https://docs.djangoproject.com/en/dev/topics/db/managers/)에 있습니다. – gw0