Python / Django中的Global Request变量是否可用?

时间:2011-09-01 08:46:19

标签: python django

我写了一个插件,发送一个信号来激活我的代码。但是,它不会将用户请求对象发送到我的代码。我正在寻找一种方法来检索当前请求而无需修改主应用程序。我找不到任何与全局请求相关的文档(例如PHP中的$_SERVER['REMOTE_ADDR'])。

我想知道在Python / Django中是否有任何变量可以做。

5 个答案:

答案 0 :(得分:17)

Django不提供全局请求对象(它实际上是本地线程,而不是全局线程)。但是您可以使用一些技术来获得相同的效果:http://nedbatchelder.com/blog/201008/global_django_requests.html

答案 1 :(得分:1)

AFAIK无法使用,除非您将其提供。

您可以复制+粘贴其他答案中提供的代码段,也可以使用此库:https://pypi.python.org/pypi/django-crequest

  

中间件使当前请求始终可用。

答案 2 :(得分:1)

您可以通过中间件将其附加到当前请求并将其检索回来 https://github.com/jedie/django-tools/blob/master/django_tools/middlewares/ThreadLocal.py

答案 3 :(得分:0)

据我所知,您可以使用以下方法定义Django视图:

def detail(request, some_param):
  # [...]

参数request包含有关HTTP请求的信息。例如request.META['HTTP_X_FORWARDED_FOR'],返回客户端的IP地址。

如果你的插件与请求有关,它的类和函数可能会从你的视图中实例化/调用。这意味着您需要将当前的request对象传递给它,因为拥有全局请求对象是没有意义的。 在PHP中,这是可能的,因为每个请求都会导致整个代码从头开始执行,但在Django中,请求由服务器调度并使用HttpRequest对象在框架中传递。有关更多信息,请参阅Django文档的this部分。

答案 4 :(得分:0)

基于Ned Batchelder的回复,我编写了一个解决方案。尽管除了调试/故障排除之外,我不建议使用它。链接页面上有一个更好的解决方案。

将模块m1放在项目根目录:

import inspect
def get_request():
    for f in inspect.stack():
        f_code = inspect.getmembers(f.frame, inspect.iscode)[0][1]
        f_locals = [v for (n, v) in inspect.getmembers(f.frame) if n == 'f_locals'][0]
        co_varnames = [v for (n, v) in inspect.getmembers(f_code) if n == 'co_varnames'][0]
        if 'request' in co_varnames:
            return f_locals['request']

然后在其他任何文件中:

import m1
print(m1.get_response().path)

您可能要确保不引入reference cycles。我不了解在什么特定条件下我必须准确地做些什么。在我看来,这并不重要。但是您的里程可能会有所不同。