webapp2 + jinja2:如何让 uri_for() 在 jinja2-views 中工作
Posted
技术标签:
【中文标题】webapp2 + jinja2:如何让 uri_for() 在 jinja2-views 中工作【英文标题】:webapp2 + jinja2: How can i get uri_for() working in jinja2-views 【发布时间】:2011-10-28 05:13:03 【问题描述】:如何将特定于模型的 url 添加到模板中。 比方说,我想建立一个编辑链接。 我猜想,使用 uri_for() 函数会是一种简单的方法。
但下面给了我“UndefinedError: 'webapp2' is undefined”
% webapp2.uri_for("editGreeting", greeting.key().id()) %
或者我应该在 MainPage-Request-Handler 中准备这些吗? 如果是这样,我不知道如何将它们添加到每个问候语中。
以下代码示例取自: http://webapp-improved.appspot.com/tutorials/gettingstarted/templates.html
控制器/处理程序
class MainPage(webapp2.RequestHandler):
def get(self):
guestbook_name=self.request.get('guestbook_name')
greetings_query = Greeting.all().ancestor(
guestbook_key(guestbook_name)).order('-date')
greetings = greetings_query.fetch(10)
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
else:
url = users.create_login_url(self.request.uri)
url_linktext = 'Login'
template_values =
'greetings': greetings,
'url': url,
'url_linktext': url_linktext,
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))
模板/视图:
<html>
<body>
% for greeting in greetings %
% if greeting.author %
<b> greeting.author.nickname </b> wrote:
% else %
An anonymous person wrote:
% endif %
<blockquote> greeting.content|escape </blockquote>
% endfor %
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
<a href=" url "> url_linktext </a>
</body>
</html
BaseHandler 类是所有处理程序都继承自的类。 我按照@moraes 的建议尝试了以下操作。 我仍然得到:
value = self.func(obj)
File "C:\Users\timme04\python\hellowebapp\handlers\basehandler.py", line 23, in jinja2
return jinja2.get_jinja2(factory=self.jinja2_factory)
File "C:\Users\timme04\python\hellowebapp\webapp2_extras\jinja2.py", line 212, in get_jinja2
jinja2 = app.registry[key] = factory(app)
TypeError: jinja2_factory() takes exactly 1 argument (2 given)
:(
import webapp2
from webapp2_extras import jinja2
class BaseHandler(webapp2.RequestHandler):
def jinja2_factory(app):
j = jinja2.Jinja2(app)
j.environment.filters.update(
# Set filters.
# ...
)
j.environment.globals.update(
# Set global variables.
'uri_for': webapp2.uri_for,
# ...
)
return j
@webapp2.cached_property
def jinja2(self):
# Returns a Jinja2 renderer cached in the app registry.
return jinja2.get_jinja2(factory=self.jinja2_factory)
def render_response(self, _template, **context):
# Renders a template and writes the result to the response.
rv = self.jinja2.render_template(_template, **context)
self.response.write(rv)
【问题讨论】:
看起来该代码示例可能缺少“import webapp2”。 我已经将 'import webapp2' 添加到我的控制器/处理程序中,但仍然无法在我的模板中使用它... 【参考方案1】:这是更简单的解决方案.. ;-) 我有...很多人可能已经知道这一点,但效果很好。
env = jinja2.Environment(
loader=jinja2.FileSystemLoader(root_path),
extensions=['jinja2.ext.autoescape',
'jinja2.ext.i18n',
CompilerExtension],
variable_start_string='[[',
variable_end_string=']]',
autoescape=True)
env.globals =
'uri_for': webapp2.uri_for
env.globals 是关键:-)
【讨论】:
【参考方案2】:您必须将uri_for
设置为全局变量。一种方法是为全局变量和过滤器设置一个初始化器:
import webapp2
from webapp2_extras import jinja2
def jinja2_factory(app):
j = jinja2.Jinja2(app)
j.environment.filters.update(
# Set filters.
# ...
)
j.environment.globals.update(
# Set global variables.
'uri_for': webapp2.uri_for,
# ...
)
return j
class BaseHandler(webapp2.RequestHandler):
@webapp2.cached_property
def jinja2(self):
# Returns a Jinja2 renderer cached in the app registry.
return jinja2.get_jinja2(factory=jinja2_factory)
def render_response(self, _template, **context):
# Renders a template and writes the result to the response.
rv = self.jinja2.render_template(_template, **context)
self.response.write(rv)
编辑:将示例更改为使用 RequestHandler。
【讨论】:
非常感谢!我真的很喜欢 webapp2...而且我认为我们正在接近解决方案。 工厂可以是一个独立的函数...不需要属于handler。 非常感谢 - 我需要这个来让“_”(gettext)函数在 i18n 上工作! :-) 为了添加扩展使用 j2.environment.add_extension('my_memcached') 对于其他无法在模板中使用它的人,您可以像这样使用它... uri_for("editGreeting", greeting.key().id())
以上是关于webapp2 + jinja2:如何让 uri_for() 在 jinja2-views 中工作的主要内容,如果未能解决你的问题,请参考以下文章
如何对从 webapp2 请求处理程序传递给 jinja2 模板的模板变量进行单元测试
在 Django 模板中使用 webapp2.uri_for