Getting a request parameter in Jinja2

Question:

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

http://foo.bar?a=1
Asked By: Shankar Cabus

||

Answers:

You will need to pass this information to your jinja2 templates, since it is just a templating engine, and not the web framework.

The “view generation” part of your web framework that deals with requests will usually be passed some HTTP request header information or data structure. this often includes the request params. If it does, then you can just pass this to your template.

Even if the header info you get doesn’t include the request params, it will always include the url. Once you have the url in your view function code, you can do something like this:

url = "http://foo.bar?a=1&b=2&c=true" # actually get this from your http request header
import urlparse
split_result = urlparse.urlsplit(url)
request_params = dict(urlparse.parse_qsl(split_result.query))
# request_params = {'a': '1', 'b': '2', 'c': 'true'}

Then you can send this request_params dictionary to your jinja template.

Answered By: Preet Kukreti

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.

Answered By: Evan Plaice

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.

Answered By: Kalle

In your Jinja2 template if you define it like below:::

<h2><a href="{{url_for('single_thing', id='2', pid='34')}}">{{some_value}}</a> </h2>

Your URI will be:::

http://127.0.0.1:5000/single_thing?pid=34&id=2
Answered By: defau1t

If you want the query parameters from url, you can use this in jinja:

request.query_string.decode()
Answered By: Ahmad
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.