首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django -收集每个请求的信息

Django -收集每个请求的信息
EN

Stack Overflow用户
提问于 2017-11-14 23:50:48
回答 2查看 246关注 0票数 0

我希望收集每个请求中的数据(单个请求可能会导致多个更改),并在请求结束时处理数据。

所以我使用一个单例类来收集数据,并在request_finished信号上处理其中的数据。它是否应该工作,或者我是否应该预料到数据丢失/其他问题?

单例类:

代码语言:javascript
复制
class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class DataManager(object, metaclass=Singleton):
     ....

在其他信号中使用它:

代码语言:javascript
复制
item_created = DataManager().ItemCreated(item)
DataManager().add_event_to_list(item_created)

请求完成信号:

代码语言:javascript
复制
@receiver(request_finished, dispatch_uid="request_finished")
def my_request_finished_handler(sender, **kwargs):
    DataManager().process_data()
EN

回答 2

Stack Overflow用户

发布于 2017-11-15 00:14:45

单例意味着每个进程只有一个实例。典型的生产Django设置是一个或多个前端服务器运行多个长时间运行的Django进程,每个进程都为任何传入的请求提供服务。FWIW你甚至可以在同一进程AFAICT的并发线程中为Django提供服务。在这种情况下,同一个用户的后续请求可以由不同的进程/线程服务,并且任何长期存在的“全局”对象都将由当前进程服务的所有请求共享。最终的结果是,正如Daniel Roseman正确地评论的那样,“在Django这样的多进程多用户环境中,单例永远不会做你想要的事情”。

如果您想收集每个请求-响应周期的数据,最好的方法是将它们存储在request对象本身上,在请求处理周期开始时使用中间件初始化收集器,并在请求处理周期结束时对收集的数据执行某些操作。当然,这需要一直传递请求...这确实有点笨拙。

这里的一个解决方法可能是将每个请求的“收集器”对象的一些方法连接为信号处理程序,注意正确设置"dispatch_uid“以便在发送响应之前断开它们,并且最好使用弱引用来避免内存泄漏。

注意:如果您想收集每个用户的信息,这就是session框架的作用,但我假设您已经了解这一点。

票数 2
EN

Stack Overflow用户

发布于 2017-11-15 15:05:46

  • 编辑了我的答案,第一个没有考虑好。

经过进一步的思考,在信号中使用请求并不是一个好主意,既不是全局的,也不是传递的。

Django有两个主要路径:视图和命令。视图用于web请求,它生成一个“request”对象。命令是通过控制台使用的,不会生成“request”对象。理想情况下,您的模型(因此,也是信号)应该能够支持两种路径(例如:在项目生命周期内进行数据迁移)。因此,将您的信号绑定到请求对象本身就是不正确的。

最好使用类似线程本地内存空间的东西,并确保线程全局类不依赖于请求中的任何内容。例如:Is there a way to access the context from everywhere in Django?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47289951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档