Django 会话序列化选择 pickle/json 的帮助

0 投票
1 回答
2315 浏览
提问于 2025-04-18 08:50

我在使用django 1.6,这个版本默认的会话数据格式是json。我把会话数据存储方式改成了数据库。
现在我把设置改成使用pickle。
在看到这篇文章后:http://www.benfrederickson.com/2014/02/12/dont-pickle-your-data.html
我对速度的巨大差异感到很惊讶。
我知道pickle有安全问题,但目前这些问题对我来说不太重要,因为我并没有序列化用户输入的数据,而且我的网站也不算特别有名。

我检查了一下我的代码,发现我在会话中存储的数据类型有:
字符串(json可以存)
布尔值(json可以存)
日期时间(json不支持,但我可以把它转成字符串,必要时再解析)
渲染对象(HttpResponse,不支持json)。
所以,正如你所看到的,如果我能解决最后一种存储类型,我就可以使用json了。
基本上,我的情况是这样的:
我执行一个SQL查询来生成某个页面。这个页面里有一个iframe(谷歌地图),它需要相同的SQL输出。所以我不想执行两次相同的SQL查询,我只是想在同一个视图中“渲染”两个页面,使用相同的上下文和查询输出,当我加载iframe时,我从会话中提取已经生成的页面。
我该如何避免这样做?有什么办法可以在同一个视图中生成两个页面?

编辑:
这是情况的详细说明。
index.html包含一个<iframe src='/map/'>

为了生成index.html,视图是:

def index(request):
    output = sql_query
    return render_to_response('index.html', {'data':output})

由于index.html中有一个iframe,会发送另一个GET请求,达到这个视图:

def map(request):
    # Here I need the same sql output I had from the index view.
    # I don't want to perform this sql again.
    # So what I did is to create the page in index view, store it in the session,
    # and just return the page from the session. like this:
    return request.session['rendered_page_from_index_view']

这就是我为什么改用pickle序列化的原因。除此之外,我也可以使用json。我该如何避免在会话中存储这个页面,而不执行两次相同的SQL查询呢?
我希望我说的很清楚。

1 个回答

0

我觉得你可能误解了会话引擎的作用,它是用来存储和获取每个访问者的数据,以解决HTTP协议的无状态特性。

如果你想节省一些SQL查询的时间,可以看看这个缓存框架

编辑
你应该从你的请求中找到一些参数,这些参数可以帮助你生成一个唯一的键(也许你可以在index中设置一个唯一的值到会话里,然后在map中取出来),然后用这个键来设置你的查询结果的缓存。

伪代码:

def index(request):
    queryset = get_my_queryset()
    unique_id = get_unique_id_from_request(request)
    request.session['queryset_id'] = unique_id
    cache.set(unique_id, queryset, 30)
    return render_to_response('index.html', {'data': queryset})

def map(request):
    unique_id = request.session.get('queryset_id')
    queryset = None
    if unique_id:
        queryset = cache.get(unique_id)
    if queryset is None:
        queryset = get_my_queryset()
    return render_to_response('map.html', {'data': queryset})

撰写回答