2010-12-03 3 views
2

간단한 캐싱 트릭이 실제로 유용할지 여부를 결정하려고합니다. 내가 장고 querysets 효율성을 향상시키기 위해 게으른지만 데이터를 호출 한 후 그들의 쿼리 결과를 저장하는 경우 궁금하네요. 예를 들어django 쿼리는 호출 된 후 결과를 저장합니까?

, 나는 두 가지 모델이있는 경우 :


class Klass1(models.Model): 
    k2 = models.ForeignKey('Klass2') 

class Klass2(models.Model): 
    # Model Code ... 
    @property 
    def klasses(self): 
     self.klasses = Klass1.objects.filter(k2=self) 
     return self.klasses 

을 그리고 어디 선가 klass_2_instance.klasses[:] 전화, 데이터베이스 액세스 및 쿼리를 반환합니다. klass_2_instance.klasses을 다시 호출하면 데이터베이스에 두 번째로 액세스 할 것인지 궁금하거나 Django 쿼리가 첫 번째 호출에서 결과를 저장합니까?

+1

'class '대신에'klass'가 끔찍한 것처럼 보였습니다. 'cls'는'class'가 오류를 일으킬 문맥에서 이름이 사용된다면 IMO로가는 길입니다. – ThiefMaster

+0

걱정하지 마시고, 여기 klass를 임의의 이름으로 사용했습니다. 이것은 내가 사용하고있는 실제 모델이 아니라 예제 코드입니다. – Arion

답변

1

장고는 캐시하지 않습니다.

대신 Klass1.objects.filter (k2 = self) 대신 self.klass1_set.all()을 사용할 수 있습니다. Django는 항상 1-N 릴레이션의 많은면에서 세트를 생성하기 때문에.

이 종류의 캐시는 모든 필터, 제외 및 사용 된 order_by를 기억해야하기 때문에 복잡합니다. 잘 설계된 해시를 사용하여 수행 할 수 있지만 적어도 캐시를 사용하지 않으려면 매개 변수가 있어야합니다. 당신이 어떤 캐시를 원하시면

, 당신이 할 수 있습니다 :

 
class Klass2(models.Model): 
    def __init__(self, *args, **kwargs): 
    self._klass1_cache = None 
    super(Klass2, self).__init__(*args, **kwargs) 

    def klasses(self): 
    if self._klass1_cache is None: 
     # Here you can't remove list(..) because it is forcing query execution exactly once. 
     self._klass1_cache = list(self.klass1_set.all()) 
    return self._klass1_cache 

매우 유용 할 때 모든 관련 개체에 당신 루프를 여러 번. 나를 위해 그것은 템플릿에서 종종 일어난다. 나는 한 번 이상 반복 할 필요가있다.

1

이 쿼리는 장고에 의해 캐시되지 않습니다.

전달 FK의 관계 - 제 조회 후 캐시 인 - klass.k2가 하 Klass 객체 klass를 부여하여 예. 하지만 여기에서하는 리버스는 보통 klass2.klass_set.all()으로 철자가 붙여져 있습니다. 은 캐시되지 않고입니다.

당신은 쉽게 그것을 memoize 수 있습니다

@property 
def klasses(self): 
    if not hasattr(self, '_klasses'): 
     self._klasses = self.klass_set.all() 
    return self._klasses 

(당신은 속성과 메소드 klasses를 오버 라이딩으로 기존의 코드가 작동하지 않습니다.)

+0

흥미롭게도, 속성 데코레이터를 사용하고 있기 때문에 실제로 작동합니다. 파이썬은 데이터를 변수'klasses'에 넣고 데코 레이팅 된 메소드에 대한 참조를 새 값에 대한 참조로 바꾼다고 가정합니다. 그러나, 당신이 말했듯이, 그것은 실제로이 상황에서 데이터를 캐쉬하지 않을 것입니다. – Arion

1

것은 조니 캐시를 사용해보십시오 querysets의 투명 캐싱을 원할 경우.

관련 문제