更新#7:
我删除了第一行并将第二行放在它的位置,第二行是我从 jinja2 链接jinja2 install docs复制的。但我仍然收到以下错误。
# from google.appengine.ext.webapp import template
from jinja2 import Template
File "/Users/brian/googleapps/YouPoll/views.py", line 271, in get
self.response.out.write(template.render(path, template_values))
NameError: global name 'template' is not defined
INFO 2012-07-08 22:43:53,053 dev_appserver.py:2952] "GET /?ID=testBSchott HTTP/1.1" 500
这个 appengine 不久前使用模板文件中的非 django 代码工作。
此外,如果我在 gae 交互式控制台中执行以下代码,它可以工作,即使它包含我认为是 jinja2 而不是 django 独有的 {%- if ... -%} 代码。
from jinja2 import Template
template = Template('{%- if True -%}Hello {{ name }}!{% endif %}')
print template.render(name='John Doe')
更新#6:
好的,我发现变量模板被定义了。它在下面。
jinja_environment.filters['datetimeformat'] = datetimeformat
class BaseHandler(webapp2.RequestHandler):
@webapp2.cached_property
def jinja2(self):
return jinja2.get_jinja2(app=self.app)
def render_template(
self,
filename,
template_values,
**template_args
):
template = jinja_environment.get_template(filename)
self.response.out.write(template.render(template_values))
更新#5:
这是我在views.py中的导入:
import jinja2
import os
import webapp2
import logging
import datetime
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import images
# from jinja2 import Environment, PackageLoader
from models import QA, PQ
TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'templates')
jinja_environment = \
jinja2.Environment(loader=jinja2.FileSystemLoader(TEMPLATE_DIR))
在我发布的一些代码中,我对 template_values 的使用如下。2 个导入提到 webapp,而不是 webapp2。但是,如果我将第一个更改为 webapp2,我会收到此错误。
File "/Users/brian/googleapps/YouPoll/views.py", line 9, in <module>
from google.appengine.ext.webapp2 import template
ImportError: No module named webapp2
INFO 2012-07-08 18:44:18,972 dev_appserver.py:2952] "GET /?ID=testBSchott HTTP/1.1" 500
如果我删除该行,我会收到此错误。
File "/Users/brian/googleapps/YouPoll/views.py", line 272, in get
self.response.out.write(template.render(path, template_values))
NameError: global name 'template' is not defined
INFO 2012-07-08 18:30:52,733 dev_appserver.py:2952] "GET /?ID=testBSchott HTTP/1.1" 500
你看到我能做些什么了吗?我提供了你需要的信息吗?
更新#3:如果我删除这 5 个 jinja2 序列/短语,则 html 表单可以正常工作。但是这 5 个序列/短语没有语法错误。他们过去工作得很好。我在第一次更新中添加了包含 django 的 Traceback,尽管我没有使用 django——只有 jinja。那么我还犯了什么错误?
在删除上面的序列/短语之前,我还在底部包含了我的 html 页面。
1
{% for choice in p.choices -%}
{% if not loop.first %}
,{% endif %}
{% if loop.last %}
or
{% endif %}
{{ choice }}
{%- endfor %}.
2 {% for selection in p.choices %} {% if not loop.first %} ,{% endif %} {% if loop.last %} 或 {% endif %} {{ choice }} {% endfor %} .
3
{{ q.answers|sum() }}
4
q.date|datetimeformat('%d-%m-%Y')
5
q.modified|datetimeformat('%d-%m-%Y')
更新结束#3
这句话出现在错误之前,工作正常。
{% if p.purpose %}
</p>
<p> The purpose of this questionnaire is {{ p.purpose }}.
</p>
{% endif %}
但是接下来的这个短语会引发错误(显然)。
{% for choice in p.choices -%}
{% if not loop.first %}
,{% endif %}
{% if loop.last %}
or
{% endif %}
{{ choice }}
{%- endfor %}.
接下来是错误。
更新#2:如果我修改“错误”“for”语句,删除空间控制“-”,系统仍会转到下面的下一个错误,但“-”并不是真正的错误。
ERROR 2012-07-06 21:46:07,107 webapp2.py:1553] 'for' statements should use the format 'for x in y': for choice in p.choices -
Traceback (most recent call last):
更新#1:
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1536, in __call__
rv = self.handle_exception(request, response, e)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1530, in __call__
rv = self.router.dispatch(request, response)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/Users/brian/googleapps/YouPoll/views.py", line 272, in get
self.response.out.write(template.render(path, template_values))
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/template.py", line 89, in render
t = _load_internal_django(template_path, debug)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/template.py", line 163, in _load_internal_django
template = django.template.loader.get_template(file_name)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader.py", line 160, in get_template
template = get_template_from_string(template, origin, template_name)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader.py", line 168, in get_template_from_string
return Template(source, origin, name)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 158, in __init__
self.nodelist = compile_string(template_string, origin)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 186, in compile_string
return parser.parse()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 281, in parse
compiled_result = compile_func(self, token)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader_tags.py", line 195, in do_extends
nodelist = parser.parse()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 281, in parse
compiled_result = compile_func(self, token)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader_tags.py", line 173, in do_block
nodelist = parser.parse(('endblock', 'endblock %s' % block_name))
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 281, in parse
compiled_result = compile_func(self, token)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/defaulttags.py", line 684, in do_for
" 'for x in y': %s" % token.contents)
TemplateSyntaxError: 'for' statements should use the format 'for x in y': for choice in p.choices -
INFO 2012-07-06 21:46:07,117 dev_appserver.py:2952] "GET /?ID=testBSchott HTTP/1.1" 500 -
如果我从模板中删除该短语,则此短语会引发错误(在跳过其他一些(%ifs 和 {%fors )之后)。
{% for q in qs|sort(attribute='seqnum') %}
接下来是错误。
ERROR 2012-07-06 21:48:38,177 webapp2.py:1553] Invalid filter: 'sort'
Traceback (most recent call last):
...
TemplateSyntaxError: Invalid filter: 'sort'
INFO 2012-07-06 21:44:03,051 dev_appserver.py:2952] "GET /?ID=testBSchott HTTP/1.1" 500 -
如果我从模板中删除该短语,则此短语会引发错误(在跳过其他一些(%ifs 和 {%fors )之后)。
<td align="right"> {{ q.answers|sum() }} </td>
如果我从模板中删除该短语,那么这个短语也会引发错误。
ERROR 2012-07-06 21:36:07,650 webapp2.py:1553] Invalid filter: 'sum'
Traceback (most recent call last):
...
TemplateSyntaxError: Invalid filter: 'sum'
等等。这看起来像是其他问题的信号。但我没有头绪。这个模板之前工作了一点,但已经停止工作,所以我怀疑我的 python 代码中有一些错误是原因,但我无法想象从哪里开始寻找。
顺便说一句,当我使用 jinja2 时,Traceback 经常提到 Django,但我认为这无关紧要。
下面是我用来提供模板的 python 代码。我留下了日志信息以显示我所做的一些调试。
qs = db.Query(QA)
qs.ancestor(person)
qs.filter('deleteRequested =', False)
qs.run()
for item in qs:
logging.info("2 seqnum %d" % item.seqnum)
for item in person.choices:
logging.info("2 choice %s" % item )
logging.info("2 title %s" % person.title )
logging.info("2 person.key()%s" % person.key())
# template_values = {'ID_id':person.key(),
template_values = { 'p': person,
'qs': qs
}
path = os.path.join(TEMPLATE_DIR, 'table.html')
logging.info("Here After Revise" )
self.response.out.write(template.render(path, template_values))
更新#4:
以下是我失败的 html 页面的列表。
{% extends "base.html" %}
{% block content %}
<center>
<h1>Make your preferences for <span class="emph">{{p.ID|escape}}</span> known here</h1>
{% if p.title %}
</center>
<p><h2> The title of this questionnaire is: {{ p.title }}.</h2> </p>
</center>
{% endif %}
<br />
<div id="inputdata">
{% if p.purpose %}
<p> The purpose of this questionnaire is: {{ p.purpose }}.
</p>
{% endif %}
<p>This is a participative preferences survey: you not only answer questions, you supply questions for all to answer.
</p>
<ol>
<li>
To answer existing questions, click on the "Radio" button in the corresponding rows of the table:
{% for choice in p.choices -%}
{% if not loop.first %}
,{% endif %}
{% if loop.last %}
or
{% endif %}
{{ choice }}
{%- endfor %}.
</li>
<li>
After answering questions, at the bottom of the page click the "Submit" button to register you answers.
</li>
</ol>
</div>
<br />
<div id="inputdata">
<p>To supply a new question or statement, click <a href="/add_question?ID={{ p.ID }}"><span class="emph">here</span></a>. At the present time there is no automated mechanism for editing or erasing an existing question.
</p>
<br />
<p>The question numbers (No's) are used to arrange the questions. You place your question in the list with the number you choose.
</p>
</div>
{% if not p.moreinfo == 'None' %}
<p> {{ p.moreinfo }}
</p>
{% endif %}
<form action="table" method="post" enctype="multipart/form-data">
<input type="hidden" name="ID" value="{{p.ID|escape}}"></input><br/>
<table border="1" cellpadding="2"
cellspacing="0" class="sortable" id="unique-id">
<thead> <tr>
<td>No</td>
<td>Question</td>
<td> Total </td>
{% for choice in p.choices %}
<td bgcolor="#fef886"> {{ choice }} </td>
{% endfor %}
<td> Created </td>
<td> Last answered </td>
</tr></thead>
<tbody>
{% if qs %}
{% for q in qs|sort(attribute='seqnum') %}
<tr>
<td align="right"> {{ q.seqnum }} </td>
<td> {{ q.question }} </td>
<td align="right"> {{ q.answers|sum() }} </td>
{# <td> {{ q.total }} </td> #}
{% for answer in q.answers %}
<td bgcolor="#fef886">
<input type="radio" name="{{q.seqnum}}" value="{{loop.index}}"
/>
{{ answer }}
</td>
{% endfor %}
<td>{{ q.date|datetimeformat('%d-%m-%Y') }}</td>
<td>{{ q.modified|datetimeformat('%d-%m-%Y')}}</td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
<br />
<div id="inputdata">
<p>To remember your own choices, print this page before ReLoading</p>
</div>
<center>
<input type="submit"
name="Submit"
value="Submit" />
</center>
</form>
<script src="/static/javascript/sorttable.js" type="text/javascript"></script>
{% endblock content %}