2012-01-04 50 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

相关问题