Django - 在request.session中存储queryset仍然查询db - 为什么?

时间:2012-01-04 23:11:38

标签: django session views

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拉出来吗?任何建议都非常感谢。

1 个答案:

答案 0 :(得分:4)

您正在会话中保存queryset个对象。查询集与SQL语句类似,但它们会缓存结果。当您将查询放入会话时,您还没有运行查询,因此您存储的内容基本上只是查询。当它被拉出时,它仍然只是一个未运行的查询,因此查询集再次运行。为确保您只存储实际结果,请执行以下操作:

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

并且当您找到count时可以保存另一个查询...

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

另外请记住,会话数据(默认情况下)保存在数据库中,因此您可能无法通过存储完整数据的python pickled表示来获得任何好处。实际上,只要转到原始表并以此方式将其拉出来就可能更快。