9

So I'm using Django with Google App Engine and I have an urls.py file that redirects each url to a corresponding method. Each one of those methods is automatically passed "request" as one of the arguments, which I believe is an HttpRequest object.

How do I create this populated request object from within my code? For example, if I'm within some method deep within my code, I'd like to have access to this request object without having to pass it to every function to make sure it's available. Assuming urls.py calls the method foo, the way I'm currently doing it is:

foo(request):
    # stuff here
    bar(request)
     # more stuff here

bar(request):
     # stuff here<stuff>
    baz(request)
     # more stuff here

baz(request):
    do something with request here

This seems wrong because I'm having to pass request through functions that don't need it just so that I have it available in baz.

I'd like to do something like:

foo(request):
     # stuff here
    bar()
    # more stuff here

bar():
     # stuff here
    baz()
     # more stuff here

baz():
    request = HttpRequest()
    do something with request here

i.e. not pass request around if I don't have to. However, doing request = HttpRequest() returns an empty request object...what I want is a fully populated version, like what is passed into each method called from urls.py.

I glanced through the documentation for HttpRequest here: http://docs.djangoproject.com/en/dev/ref/request-response/ but didn't see the way to do it.

Any thoughts would be greatly appreciated.

Thanks, Ryan

ryan
  • 2,311
  • 3
  • 22
  • 28

3 Answers3

4

request = HttpRequest() will give you a empty one, but you can write something to it.

Here is an example I used in my project :

def new(request):
    ...
    newrequest = HttpRequest()
    newrequest.method = 'GET'
    newrequest.user = request.user
    resp = result_email(newrequest , obj-id , token )
    send_email( resp , ... )
    return HttpResponseRedirect( ... )
    ...
def result_email(request , ...):
    ...
    return render(request , ...)
Rob
  • 26,989
  • 16
  • 82
  • 98
tonge
  • 41
  • 2
  • What if you wanted to create a POST request with a body? The body attribute is immutable so this approach wont work. – Frikster Oct 26 '22 at 23:59
1

Instead of creating your own, you can get an almost real one from test package. Something like that:

from django.test import Client

client = Client()

# So here you can imitate needed you request with specific method
request = client.get('/').wsgi_request # or client.get('/').request

print(request.user)
>>> AnonymousUser
mrvol
  • 2,575
  • 18
  • 21
0

Just create a request variable before the view definitions and set its value when you receive it from the view (using your example code):

current_request = None

foo(request):
    current_request = request
    # stuff here
    bar()
    # more stuff here

bar():
     # stuff here
    baz()
     # more stuff here

baz():
    # do something with currest_request here

See: Notes on Python variable scope

Update: This question is very similar to yours and the accepted solution is basically creating a global request variable and attaching it to the settings.

Community
  • 1
  • 1
Lance McNearney
  • 9,410
  • 4
  • 49
  • 55
  • Sorry Lance, I don't think I did a good job explaining what the issue was in my original posting. I've since updated it...hopefully it's clearer now. – ryan Jan 19 '10 at 23:36
  • 1
    I still think the question has to do with the variable scope. I've updated my answer to use a global variable. – Lance McNearney Jan 19 '10 at 23:45
  • Thanks Lance. My functions are all in different .py files, and I really don't want to go the route of using a global variable. – ryan Jan 20 '10 at 17:02
  • Take a look at the other question I linked to in my last edit. If you do find a better solution please let us know. – Lance McNearney Jan 20 '10 at 17:20
  • Not the prettiest way to do it, but thank link works for me. Thanks – ryan Jan 20 '10 at 18:19