序列化Django请求对象

10 投票
2 回答
7286 浏览
提问于 2025-04-16 00:20

我想把一个请求对象保存起来,这样我就可以在调试器中用有效的输入来运行我的视图代码。不过,我遇到了这个问题:

Can't pickle 'lock' object: <thread.lock object at 0x93ad240>

我查看了请求对象,但在里面找不到任何线程锁对象。有没有人知道它在哪里?有没有更好的方法来解决这个问题?

2 个回答

6

好的,给那些感兴趣的人,我成功地将 HttpRequestWSGIRequest 对象进行了序列化。首先,你需要对至少一个类进行修改,这里是 WSGIRequest(可能还需要 HttpRequest),让它能够使用一个叫 __reduce__(self) 的方法。你可以这样做:

WSGIRequest.__reduce__= __reduce__

这个 reduce 方法可能看起来像这样:

def __reduce__(self):
    meta = dict([(k,self.META[k]) for k in METACOPY if k in self.META and isinstance(self.META[k], str)])
    return (HttpRequest, (), {'META':meta, 'POST':self.POST, 'GET':self.GET, 'user':self.user, 'path':self.path})

其中 METACOPY 是你想要保留的键的列表,比如 ['REMOTE_ADDR']。

我觉得这种方法比之前用的负载方法更方便,也更清晰。

7

一般来说,你不能把HTTP请求对象保存成一个文件(也就是“序列化”)用于任何网络服务器。序列化的过程并不是把对象本身保存下来,而是把它所引用的所有东西都保存下来。

通常,网络服务器的设计模式是让每个HTTP请求在自己的线程中运行。线程和HTTP请求之间必须有连接。因此,HTTP对象的生命周期是和网络服务器绑定在一起的,不能把它从网络服务器的环境中拿出来。

你可能想要做的是保存HTTP请求对象的内容,然后用这些内容重新创建请求。

撰写回答