2012-03-10 115 views
24

如何在Jinja2模板中检索请求参数a在Jinja2中获取请求参数

http://foo.bar?a=1 
+1

您使用Jinja2的框架是什么? – 2012-03-10 15:31:24

+0

烧瓶。但我想在模板(.html)中检索这个参数,而不是在.py文件中。 @DevinM – 2012-09-01 03:20:18

回答

43

我对这个答案有点晚了,但其他解决方案并没有真正考虑到你使用Flask。

事实上,你在Jinja2上使用Flask会让你的情况与其他框架有所不同。 Flask实际上使所有Jinja2模板中的某些全局变量可用,而不需要您明确地将它们传递给模板。

要在http://flask.pocoo.org/docs/templating/#standard-context引用文档瓶的一部分:

以下全局变量是内Jinja2的模板默认情况下可用:

...

要求 当前请求对象(flask.request)

...

因此,例如,以显示请求参数“一个”模板:

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

的文档链接还列出了可以以类似的方式访问其他全局变量。

0

您需要将这些信息传递给jinja2模板,因为它只是一个模板引擎,而不是web框架。

处理请求的Web框架的“视图生成”部分通常会传递一些HTTP请求标头信息或数据结构。这通常包括请求参数。如果是这样,那么你可以将它传递给你的模板。

即使您获取的标题信息不包含请求参数,它也会始终包含url。一旦你的网址在您的视图功能的代码,你可以做这样的事情:

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'} 

然后你可以发送该request_params字典您神社模板。

+0

但许多控制器使用相同的模板。所以我需要在所有控制器上执行此操作,但只能在模板中执行一次时=/ – 2012-03-10 17:38:55

+1

根据您的Web框架,它可能支持包装视图或其他图层的“中间件”类型系统。这意味着在你的视图函数之前,请求参数是由你的自定义中间件提取的,并且在你的视图函数之后,这些请求参数会自动附加到jinja模板。即使没有这样的机制,你可以轻松地做一些类似的装饰。大多数Web应用程序都支持中间件,因为它是WSGI中的一个中心概念。 – 2012-03-10 18:54:20

+1

但如何检索模板(.html)这个参数?有可能的? – 2012-09-01 03:21:14

3

如果您使用webapp2的...

如果你使用webapp2.request像一本字典的查询参数可以很容易地取出。

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

要应用的样品(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 

如果你只是想未解析查询字符串只拨打:

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

一旦你收集了你的变量只是将它们传递到jinja2.render_template()方法一样,你会什么都重要。

它确实没有那么容易。

更新:

我必须管理参数相当独特的方式,但我会尽力解释简单的版本。

假设下面的查询字符串

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

以下是我会写的GET处理程序:

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) 

所以,我用的实现是有点不同。我还堆叠了一个通过路由器传入的_defaults参数和一个通过在自定义url结构上进行uri查找而创建的_meta(即title/description/url)参数。

在我的基础处理程序中,我设置了jinja并将该实例包装在一个更容易调用的方法(即render_template)中。我没有想出这个想法,我想我从webapp2文档中得到它,但我离题了。

重要的部分是'上下文'参数。这就是您要将所有要发送到模板的数据堆叠起来的地方。现在,该对象中可用的任何值现在都将在模板中可用。

例如,你可以打印值“A”使用:

{{ a }} 

如果在值的阵列通过如也可以通过它们列举的参数之一,并调用直接使用点的特定属性符号。

您的处理程序的结构完全取决于您。与许多框架不同,GAE在这方面提供了很大的灵活性。我这样做的方式涉及很多继承,所以我不必重复太多。在没有粘贴我的整个handlers.py的情况下更好地详细解释有点困难,但这是我的基本处理程序的要点,我的所有其他处理程序都从此继承。唯一显着的区别是我将context定义为self.context,以便子类可以访问它。在代码中看起来相当复杂,但一旦所有东西都连接起来,几乎毫不费力地添加额外的页面/路由。

+1

但如何检索模板(.html)中的这个参数?有可能的? – 2012-09-14 17:07:03

+0

@ShankarCabus不,您将参数从python传递到模板中。我已经更新了我的答案以说明如何。 – 2012-10-30 21:48:31