2012-01-04 3 views
3
def mysearch(request): 
    """This view builds a Q object query based on which fields are filled.""" 
    if 'submit' in request.POST: 
     # build Q object depending on fields submitted 
     q = Q() 
     if request.POST['first_field']: 
      q &= Q(firstfield__icontains = request.POST['first_field']) 

     ... 

     if request.POST['sixth_field']: 
      q &= Q(sixthfield__icontains = request.POST['sixth_field']) 

     results_list = MyModel.objects.filter(q) 
     count = len(results_list) 

     # store results 
     request.session['results_list'] = results_list 
     request.session['count'] = count 

    # 'p' is an arbitrary marker to detonate pagination of a page other than 1 
    if 'p' in request.GET: 
     results_list = request.session['results_list'] 
     count = request.session['count'] 

    if count and count > 0: 
     ... 
     # pagination code 
     ... 

    else: 
     pass 
    return render_to_response('search_results.html', 
     locals(), context_instance=RequestContext(request)) 

페이지 템플릿을 사용하는 모든 템플릿에서 잘 작동합니다. 문제는 Django 디버그 툴바가 첫 번째 페이지에 비해 페이지 수가 1만큼 많은 데이터베이스를 조회한다는 것입니다. 왜 이런거야? 사실 - 왜 데이터베이스를 때리는거야? request.session에서 전체 results_list을 가져 오지 않아야하나요? 어떤 조언을 많이 주셨습니다.Django - request.session에 queryset을 저장하면 여전히 db를 쿼리합니다 - 왜?

답변

4

세션에 queryset 개체를 저장하고 있습니다. 쿼리 집합은 SQL 문과 비슷하지만 결과를 캐시합니다. 쿼리를 세션에 넣을 때 쿼리를 실행하지 않았으므로 저장 대상은 본질적으로 쿼리입니다. 꺼내지면 아직 실행되지 않은 쿼리이므로 쿼리 세트가 다시 실행됩니다.

request.session['count'] = len(request.session['results_list']) 

이 또한 마음이 세션에서 계속 ...

request.session['results_list'] = list(results_list) 

당신은 당신이 할 수있는 count을 찾을 때 또 다른 쿼리를 저장 : 당신은 그냥 실제 결과를 저장하고 있는지 확인하려면 다음을 수행 데이터는 (기본적으로) 데이터베이스에 저장되므로, 파이썬 피클 링 된 전체 데이터 표현을 저장함으로써 어떤 호의도하지 않을 수 있습니다. 실제로 원래 테이블로 이동하여 그런 식으로 꺼내는 것이 더 빠를 수도 있습니다.

+0

큰 조언. 감사. 또한 - 세션 데이터가 기본적으로 db에 저장되었다는 것을 알지 못했습니다. –

+0

세션 저장소를 memcached로 옮길 수 있습니다.이 세션 저장소는 서버에 충분한 RAM이있는 한 데이터베이스에서로드를 이동시켜 일반적으로 성능을 향상시킵니다. 성능면에서 운영상의 복잡성을 상쇄하고 있습니다. – Leopd

관련 문제