2013-07-30 3 views
0

저는 간단히 이해가 안됩니다. 내 장고 애플 리케이션에서 prefect_related의 교과서 케이스를 구현하려고하지만, 그것은 단순히 작동하지 않습니다. 다음은 관련 모델입니다 :prefetch_related가 캐시되지 않습니다.

class CanUseUnit(models.Model): 

    objects = UnitManager() 

    ingredient = models.ForeignKey('Ingredient', db_column='ingredient', related_name='useable_units') 
    unit = models.ForeignKey('Unit', related_name='used_by', db_column='unit', limit_choices_to=models.Q(parent_unit__exact=None)) 

이 모델은 사용자 정의 관리자를 가지고 있지만,이 get_all_info()라는 이름의 단지 1 방법 models.Managar의 간단한 서브 클래스가 있습니다, 그래서 나는 그와 아무 상관이 있다고 생각하지 마십시오 내 문제 :

나는 모든 성분을 조회하려고하며 사용 가능한 단위를 프리 페치하려고합니다. 이건 내 장고 쿼리입니다 :

def list_ingredients(request): 
    ingredients = Ingredient.objects.all().order_by('accepted', 'name').prefetch_related('useable_units') 
    for ingredient in ingredients: 
    print(ingredient.useable_units.all()) 

    return render(request, 'admin/list_ingredients.html', {'ingredients': ingredients}) 

그러나 장고 모든 print 문에서 데이터베이스를 칠 것 같다 ... 무슨 일입니까?

편집 :

이 템플릿에서 호출 할 때 캐싱 작업을 수행 것으로 보인다. 나는 위의보기에서 인쇄 문을 생략하고, 포함 된 템플릿 코드 다음 페이지를 방문 할 때 :

데이터베이스에만 두 번 타격을 받고있다
{% for ingredient in ingredients %} 
<tr> 
    <td><a href="/ingredients/edit/{{ ingredient.id }}/">{{ ingredient.name }}</a></td> 
    <td align="center">{{ ingredient.useable_units.count }}</td> 
</tr> 

{% endfor %} 

(I 기대하는, 한 번 성분에 대한, 그리고 한 번 prefetch_related에 대한).

해결 : 글쎄,이 문제는 해결 된 것처럼 보였습니다 ... 테스트 서버를 계속해서 다시 시작하고 갑자기 모든 성분에 대해 질의를 중단했습니다. 무슨 일이 일어 났는지는 모르지만 나는 그 문제가 해결되어 기쁘다. 당신이 문서를 보면

답변

0

문제점을 발견했습니다. Schacki의 대답은 틀렸고 프리 페치 관련은 실제로 모든 재료에 대해 하나가 아닌 2 개의 쿼리 만 필요로합니다.

중간 모델의 속성을 표시하는 템플릿의 다른 부분에 오류가있었습니다.

ingredients = Ingredient.objects.all().order_by('accepted', 'name').prefetch_related('canuseunit_set') 

대신 :

ingredients = Ingredient.objects.all().order_by('accepted', 'name').prefetch_related('useable_units') 
-2

는 : https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related, 그것은

반면에, prefetch_related 말한다 각 관계에 대해 별도의 조회를 수행하고, 파이썬

에 '가입'
을한다

제 생각에, 이것은 정확하게 당신이 보는 것입니다.

+0

글쎄, 내가 허용 대답에서, 내가 믿게 한 이전 SO 질문을 발견

그래서 내가 무엇을 했어야하는 것은 다음을이었다 (모든 성분에 대해 1이 아닌) 2 개의 쿼리 만 수행 할 것입니다. [link] (http://stackoverflow.com/questions/11746229/django-left-join-efficiently)하지만 그렇지 않은 경우에는 일괄 처리 prefetch_related하는 방법? – Gargamel

+0

오해가있는 것 같습니다. 관계는 ForeignKey 관계입니다. "각 관계에 대해"는 모든 ForeignKey, OneToOne, ManyToMany 등을 의미합니다. 그렇습니다. 귀하의 경우에는 2이지만, 게시 한 내용도 정확합니다. 그것은 당신의 질문에 대답하지 않지만 실제로 잘못이 아닙니다. – CrazyCasta

관련 문제