如何通过 Django 中的中间件创建模型中可访问的全局变量?

How to create global variables accessible in models via middleware in Django?

我目前正在使用以下代码在我的 Django models 中获取 request 对象:

request_user = None
for frame_record in inspect.stack():
    if frame_record[3] == 'get_response':
        request_user = frame_record[0].f_locals['request'].user

虽然这可行,但我想知道如何在可以在我的模型中直接轻松访问的中间件中公开请求对象?

我知道如何创建中间件我的问题是 "can be" 在模型有权访问的中间件中设置了什么?我只能看到无法在模型中直接访问的请求。 Django 是否有每个会话的全局变量设置或类似的东西?

执行此操作的最直接(也是最不容易出错)的方法是简单地创建一个您从视图中调用的新函数,并传入请求以及您需要的任何其他参数。

通常您希望分离您的关注点,这样模型方法应该只真正采用基本原子类型(字符串、字典、列表、数字等)或其他模型实例。处理请求和响应的东西应该是视图层的函数,而用于在模板中格式化的东西显然是模板辅助函数。这将有助于以后更轻松地重构或重新设计。

全局变量永远不是答案。

我认为在中间件中设置一些东西不是一个好方法。

如果您只需要访问 request 对象,那么您应该将请求传递给您的模型。您可以在那里访问 request.userrequest.META 字典。

我认为您应该实施 process_request() 而不是设置变量。

虽然这通常不是这样做的方法,但有时是有原因的(我们在我们的模型上使用管理器,只允许 return 当前用户可以看到的对象——它想知道请求,我们不控制调用函数的参数。

我们使用 django-tls 来实现这一点。是一个把请求放到全局的中间件。

但是,一般来说,您的模型不应该知道 HTTP 之类的东西存在,或者对用户界面做出任何假设。理想情况下,依赖关系应该 运行 只在一个方向上:视图知道模型存在,所以模型不应该知道视图存在。如果您必须在 Celery 任务、管理命令或随机 Python 代码中执行相同的操作,您会很高兴。