【问题标题】:Pickling Django request objectsPickling Django 请求对象
【发布时间】:2010-06-23 16:40:11
【问题描述】:

我正在尝试腌制一个请求对象,以便我可以在具有有效输入的调试器中运行我的视图代码。但是,我得到了

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

我查看了请求对象,但在其中的任何地方都找不到 thread.lock 对象。有谁知道它在哪里?有没有更好的方法来解决这个问题?

【问题讨论】:

  • 为什么不能直接在调试器中运行代码而不是尝试复制所有状态?
  • 好吧,我正在尝试调试在 Web 请求进入时运行的视图代码。我想我认为只调试视图文件并传入会更干净/更简单一个罐头请求,而不是在调试器下运行所有​​ django 并建立实际连接。
  • 另外,我很好奇这里发生了什么。
  • “不建立连接”是指不想将视图连接到 urlsconf 吗?
  • 这已经不紧急了——很久以前,我继续在调试器下运行主 Django 进程,它工作正常。但是,能够做我正在尝试的事情似乎仍然很好。我想在调试器下只运行我的views.py 文件,与Django 的其余部分完全分离。为此,我想腌制一个有效的 HttpRequest,然后取消腌制它并在其上调用有问题的视图方法。

标签: python django pickle


【解决方案1】:

通常,您不能为任何 Web 服务器腌制 HTTP 请求对象。腌制过程不会腌制对象本身,而是腌制它的所有引用。

通常的 Web 服务器设计模式是让每个 HTTP 请求运行自己的线程。线程和 HTTP 请求之间必须有连接。因此,HTTP 对象与 Web 服务器的生命周期相关联,不能脱离 Web 服务器上下文。

您可能想要做的是挑选 HTTP 请求对象的内容并使用此内容作为有效负载重新创建请求。

【讨论】:

  • 我正在尝试做一些类似于原始海报的事情。你知道如何“腌制 HTTP 请求对象的内容并使用此内容作为有效负载重新创建请求。”?我在网上找不到有关如何执行此操作的任何文档。
  • 您找不到文档,因为您不能指望有人已经为您解决了所有问题:) docs.djangoproject.com/en/1.3/ref/request-response 只需选择 request.POST 或 request.GET 有效负载或包含来自用户的所有内容的任何内容。
【解决方案2】:

好的,对于那些感兴趣的人,我已经设法腌制了 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']

我发现它比 payload 方法(我之前在 celery 中使用过)更方便、更透明。

【讨论】:

  • 这就是问题的关键——来自wsgi 的一些不可提取的对象存储在 META 字典中
  • 如果我没记错的话,请求的属性中还有一个不可拾取的线程锁对象。
  • 这里,session 也不能选择。附加了一些 lambda
猜你喜欢
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 1970-01-01
  • 2017-04-30
  • 1970-01-01
  • 2020-06-19
  • 2020-11-04
  • 1970-01-01
相关资源
最近更新 更多