Getting a request parameter in Jinja2


Question

How can I retrieve a request param a in Jinja2 template?

http://foo.bar?a=1
1
36
6/1/2013 6:49:18 PM

Accepted Answer

I'm a bit late with this answer, but the other solutions don't really account for your use of Flask.

The fact that you're using Flask with Jinja2 makes your situation a bit different from other frameworks. Flask actually makes some global variables available to you in all Jinja2 templates without requiring you to pass them to the template explicitly.

To quote a part of the Flask documentation at http://flask.pocoo.org/docs/templating/#standard-context:

The following global variables are available within Jinja2 templates by default:

...

request The current request object (flask.request)

...

So for example to show the request parameter 'a' in the template:

{{ request.args.get('a') }}

The documentation link also lists the other global variables you can access in a similar way.

61
6/1/2013 6:30:29 PM

If you're using webapp2...

The query parameters can be fetched easily if you use webapp2.request like a dictionary.

webapp2.request.get('[parameter]', '[optionalDefaultValue]')

To apply your sample (http://foo.bar?a=1&b=2&c=true):

a = webapp2.request.get('a') # a = 1
b = webapp2.request.get('b') # b = 2
c = webapp2.request.get('c') # c = true, may need further parsing to make it bool

If you just want the un-parsed querystring just call:

qstring = webapp2.request.query_string 
# qstring = '?a=1&b=2&c=true

Once you have collected your variables just pass them into the jinja2.render_template() method the same as you would anything else.

It really doesn't get much easier than that.

Update:

I have a pretty unique way to manage parameters but I'll try to explain the simple version.

Assuming the following querystring

http://foo.bar?a=1&b=2&c=true

Here's how I'd write the GET handler:

class BaseHandler(webapp2.RequestHandler): 
  def jinja2(self):
    return jinja2.get_jinja2(app=self.app)

  def render_template(self, template, **context):
    self.response.write(self.jinja2.render_template(template, **context))

  def get(self, **params):
    context = {}    
    context['a'] = webapp2.request.get('a')
    context['b'] = webapp2.request.get('b')
    context['c'] = webapp2.request.get('c')
    self.render_template([template], **context)

So, the implementation I use is a little different. I also stack on a _defaults parameter that gets passed in through the router, and a _meta (ie title/description/url) parameter that is created by doing a uri lookup on a custom urls structure.

In my base handler, I setup jinja and wrap the instance in a method that's easier to call (ie render_template). I didn't come up with this idea, I think I got it from the webapp2 docs but I digress.

The important part is the 'context' parameter. That's where you stack in all the data you want to send to the template. Now, any value that is available in that object will now be available in the template.

For instance you could print the value for 'a' using:

{{ a }}

If you pass in an array of values as one of the parameters you can also enumerate through them and call specific properties directly using dot notation.

How your handlers are structured is completely up to you. Unlike a lot of frameworks, GAE provides a lot of flexibility in this aspect. The way I do it involves a lot of inheritance so I don't have to repeat much. It's a little difficult to explain in better detail without pasting my whole handlers.py but this is the gist of my base handler that all the rest of my handlers inherit from. The only notable difference is I define context as self.context so the child classes can access it. It seems pretty convoluted in the code but once everything is wired up, it's almost effortless to add additional pages/routes.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon