2012-01-04 48 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)) 

所有在我的模板使用paginator運作良好。問題在於,Django調試工具欄告訴我,在頁面> 1時,我的數據庫訪問次數與我在第一頁上的次數相同。爲什麼是這樣?事實上 - 爲什麼它打到數據庫呢?整個results_list不應該從request.session被拉?任何建議非常感謝。Django - 在request.session中存儲queryset仍然查詢db - 爲什麼?

回答

4

您正在會話中保存一個queryset對象。查詢集像SQL語句,但它們緩存結果。當您將它放入會話中時,您還沒有運行查詢,因此您存儲的內容基本上只是查詢。當它被取出時,它仍然只是一個沒有運行的查詢,所以查詢集再次運行。爲了確保你剛剛保存的實際效果,這樣做:

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

,當你發現count你可以節省您的另一查詢...

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

也請記住這屆會議數據是(默認情況下)保存在數據庫中的,因此您可能不會通過存儲完整數據的python pickle表示來做任何好處。事實上,只要走到原來的桌子並以這種方式拉出來,速度可能會更快。

+0

偉大的建議。謝謝。此外 - 我不知道會話數據默認保存到數據庫。 – 2012-01-05 00:29:08

+0

您可以將會話存儲移動到memcached中,只要您的服務器上有足夠的RAM,它就會將數據從數據庫中移出並提高性能。你正在爲了性能而犧牲運營複雜性。 – Leopd 2012-01-06 18:12:16

相關問題