简体   繁体   English

Python/Django 中的全局请求变量是否可用?

[英]Is the Global Request variable in Python/Django available?

I have written a plugin that sends a signal to activate my code.我编写了一个插件来发送信号来激活我的代码。 However, it doesn't send the user-request object to my code.但是,它不会将用户请求对象发送到我的代码。 I am looking for a way to retrieve the current request without modifying the main application.我正在寻找一种无需修改主应用程序即可检索当前请求的方法。 I cannot find any documentation related to global request (like $_SERVER['REMOTE_ADDR'] in PHP).我找不到任何与全局请求相关的文档(如 PHP 中的$_SERVER['REMOTE_ADDR'] )。

I would like to know if there are any variable to do like that in Python/Django.我想知道在 Python/Django 中是否有任何变量可以这样做。

Django doesn't provide a global request object (it would actually be a thread local, not a global). Django不提供全局请求对象(它实际上是本地线程,而不是全局线程)。 But there are a few techniques you can use to get the same effect yourself: http://nedbatchelder.com/blog/201008/global_django_requests.html 但是您可以使用一些技巧自己获得相同的效果: http : //nedbatchelder.com/blog/201008/global_django_requests.html

AFAIK it is not available, except you make it available. AFAIK它不可用,除非您使其可用。

You can copy+paste the snippets provided in the other answers, or you can use this library: https://pypi.python.org/pypi/django-crequest 您可以复制并粘贴其他答案中提供的代码段,也可以使用以下库: https : //pypi.python.org/pypi/django-crequest

Middleware to make current request always available. 使当前请求始终可用的中间件。

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

Based on Ned Batchelder's reply I've compiled a solution. 基于Ned Batchelder的回复,我已经编译了一个解决方案。 Although I wouldn't recommend it for anything but debugging/troubleshooting. 尽管除了调试/故障排除之外,我不建议使用它。 There's a better solution on the linked page. 链接页面上有一个更好的解决方案。

Put module m1 at a project root: 将模块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']

Then in any other file: 然后在任何其他文件中:

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

You might want to make sure you don't introduce reference cycles . 您可能要确保不引入参考循环 I haven't understood under which particular conditions I must do what exactly. 我不了解在什么特定条件下我必须准确地做些什么。 Not that it matters in my case. 在我看来,这并不重要。 But your mileage might vary. 但是您的里程可能会有所不同。

One solution is django-middleware-global-request .一种解决方案是django-middleware-global-request

It provides a way to get the request from anywhere once the request has been constructed by Django in the first place.一旦请求首先由 Django 构建,它提供了一种从任何地方获取请求的方法。 It returns None if no request object is available, for example when running in a manage.py shell .如果没有可用的请求对象,例如在manage.py shell运行时,它返回None

As I know it, you define your Django view using a number of methods like: 据我所知,您可以使用多种方法定义Django视图:

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

The parameter request contains information about the HTTP request. 参数request包含有关HTTP请求的信息。 request.META['HTTP_X_FORWARDED_FOR'] for example, returns the client's IP address. 例如, request.META['HTTP_X_FORWARDED_FOR']返回客户端的IP地址。

If your plugin has something to do with requests, its classes and function probably will be instantiated/called from your view. 如果您的插件与请求有关,则可能会从您的视图中实例化/调用其类和函数。 This means you need to pass it the current request object, as it makes no sense to have a global request object around. 这意味着您需要将当前request对象传递给它,因为周围没有全局请求对象是没有意义的。 In PHP, this is possible, as every request causes the whole code to be executed from scratch, but in Django requests are dispatched by a server and passed around in the framework using HttpRequest objects. 在PHP中,这是可能的,因为每个请求都会导致整个代码从头开始执行,但是在Django中,请求是由服务器分派的,并使用HttpRequest对象在框架中传递。 Also refer to this part of the Django documentation for more information. 另请参阅Django文档的部分以获取更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM