开发者

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).

I would like to know if there are any variable to do like that in Python/Dja开发者_JAVA百科ngo.


Django doesn't provide a global request object (it would actually be a thread local, not a global). But there are a few techniques you can use to get the same effect yourself: http://nedbatchelder.com/blog/201008/global_django_requests.html


AFAIK it is not available, except you make it available.

You can copy+paste the snippets provided in the other answers, or you can use this library: https://pypi.python.org/pypi/django-crequest

Middleware to make current request always available.


you can attach it to current request via middleware and retrieve it back https://github.com/jedie/django-tools/blob/master/django_tools/middlewares/ThreadLocal.py


Based on Ned Batchelder's reply I've compiled a solution. 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:

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.

It provides a way to get the request from anywhere once the request has been constructed by Django in the first place. It returns None if no request object is available, for example when running in a manage.py shell.


As I know it, you define your Django view using a number of methods like:

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

The parameter request contains information about the HTTP request. request.META['HTTP_X_FORWARDED_FOR'] for example, returns the client's IP address.

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. 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. Also refer to this part of the Django documentation for more information.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜