如何为Django模型对象定制pickle

4
我的应用程序使用“每个用户会话”来允许同一用户的多个会话共享状态。它的操作方式与 Django 会话非常相似,都是通过 pickling 对象实现的。
我需要 pickling 一个引用了 Django 模型对象的复杂对象。标准的 pickling 过程会将一个反规范化的对象存储在 pickle 中。因此,如果在 pickling 和 unpickling 之间数据库中的对象发生更改,则模型现在已过时。(我知道内存中的对象也是如此,但 pickling 是解决这个问题的方便时机。)
显然,将这个复杂对象存储在数据库中会更简洁,但这并不切实际。它的代码随着项目的发展而必然不断变化。每当对象的数据模型发生变化时,都必须更新数据库模式,这会大大减慢项目的进度。
所以,我希望能够不要 pickle 完整的 Django 模型对象。而只是存储它的类和 ID,并在加载时从数据库中重新获取内容。我可以为这个类指定一个自定义的 pickle 方法吗?如果有办法进行 pickling,那么我很乐意编写一个 wrapper 类来处理从数据库中延迟获取,

为什么要使用 pickle 来保存你的数据?你能给出更多细节吗?在我看来,你最好将数据保存在数据库中。 - Zach
是的,将其存储在数据库中会更加清晰,但这并不切实际。我要保存的对象非常复杂,并且随着项目的发展必然会快速变化。每次更改此对象存储内容的任何内容都必须更新数据库模式,这将使项目停滞不前。 - muudscope
请在您的问题中更新附加事实。您拥有这个问题;您不仅限于串联评论。请更新问题。请解释为什么JSON不适合您的问题。 - S.Lott
2个回答

1

你的目标不太清晰。

“但是如果我只是将id和class存储在元组中,那么每次使用任何django对象时,我都必须返回到数据库。我希望能够在页面请求期间将我正在使用的对象保存在内存中。”

这没有意义,因为视图函数就是一个页面请求,并且您的视图函数中有局部变量,可以使您的对象保留到完成为止。

此外,Django的ORM具有缓存。

最后,Django提供的会话是“请求之间的内存对象”的常规位置。

您不应该需要pickle任何内容。


哦,没有考虑到ORM缓存。如果我只使用id/class元组方法,那对我来说可能足够了。出于与会话相同的原因,我需要pickle,但内置会话范围过于严格——我有一个“用户作用域”会话,而不是浏览器作用域会话。由于封装原因,在视图方法中加载这些对象毫无意义。总之,感谢您的建议。 - muudscope
什么是“用户范围”的会话?请更新您的问题以解释您正在做什么。在视图函数中执行此操作怎么可能没有意义呢?那就是页面请求的本质。 - S.Lott

0

您可以重载序列化方法。但是,将id和class放入元组或字典中并对其进行pickle处理会更简单。


但是,如果我只是将id和class存储在元组中,那么每次使用任何django对象时,我必须返回到数据库。我希望能够在页面请求期间将我正在使用的对象保留在内存中。问题是,如果我将它们放入内存中,那么它们就会被pickle。如何重载序列化方法?我在pickle文档中没有看到任何相关内容。谢谢。 - muudscope
但为什么不只是将它们缓存起来呢?这就是 Django 缓存的作用。 - Tom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接