1

我在使用 Jinja2 的 Google App Engine 上收到 TemplateNotFound 错误(下面是完整的堆栈跟踪。)

我希望看到的是带有“greet”变量的 index.html 传递给 index.html 模板文件。我不明白为什么当 TraceBack 中 index.html 的路径正确时,我得到模板未找到错误。

我试过的...

  • 通过在模板路径中取出“os.path.dirname( file )”来尝试相对路径。
  • 使用“模板”而不是主题作为目录名称。

这是我的代码。

应用程序.yaml

application: codemywayout
version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:

- url: /admin/.*
  script: admin.app
  login: admin

- url: /static/([^/]+)/(.*)
  static_files: template/\1/static/\2
  upload: static/.*

- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: .*
  script: static.app

builtins:
- remote_api: on

libraries:
- name: webapp2
  version: "2.5.1"
- name: jinja2
  version: latest

管理员.py

from google.appengine.ext import db
import webapp2
import jinja2
import os
import fix_path
import config


def render_template(template_name, template_vals=None, theme=None):
    template_path = os.path.join(os.path.dirname(__file__) , \
            "themes", theme or config.theme, template_name)
    env = jinja2.Environment(
        loader=jinja2.FileSystemLoader(template_path))
    return env.get_template(template_path, template_vals or {})

class BlogPost(db.Model):
    title = db.StringProperty()
    body = db.StringProperty()

def render(self):
    template_vals = {
        'config': config,
        'post': self,
    }
    return render_template("post.html", template_vals)

class BaseHandler(webapp2.RequestHandler):
    def render_to_response(self, template_name, \
            template_vals=None, theme=None):
        template_name = os.path.join("admin", template_name)
        self.response.out.write(render_template(template_name,\
            template_vals, theme))

class AdminHandler(BaseHandler):
    def get(self):
        greet = "hello"
        template_vals = {
            'greet': greet
        }
        self.render_to_response("index.html", template_vals)

配置文件

# Name of the blog
blog_name = 'My Blog'

# Selects the theme to use. Theme names correspond to directories under
# the 'themes' directory, containing templates and static content.
theme = 'default'

# Defines the URL organization to use for blog postings. Valid substitutions:
#   slug - the identifier for the post, derived from the title
#   year - the year the post was published in
#   month - the month the post was published in
#   day - the day the post was published in

# URL Options
#   post_path_format = '/%(year)d/%(month)02d/%(slug)s'
post_path_format = '/%(slug)s'

追溯

Traceback (most recent call last):
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 1536, in __call__
    rv = self.handle_exception(request, response, e)
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 1530, in __call__
    rv = self.router.dispatch(request, response)
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "C:\Users\john\webdev\workspace\codemywayout\admin.py", line 49, in get
    self.render_to_response("index.html", template_vals)
  File "C:\Users\john\webdev\workspace\codemywayout\admin.py", line 34, in render_to_response
    template_vals, theme))
  File "C:\Users\john\webdev\workspace\codemywayout\admin.py", line 14, in render_template
    return env.get_template(template_path, template_vals or {})
  File "C:\Users\john\webdev\google\lib\jinja2\jinja2\environment.py", line 719, in get_template
    return self._load_template(name, self.make_globals(globals))
  File "C:\Users\john\webdev\google\lib\jinja2\jinja2\environment.py", line 693, in _load_template
    template = self.loader.load(self, name, globals)
  File "C:\Users\john\webdev\google\lib\jinja2\jinja2\loaders.py", line 115, in load
    source, filename, uptodate = self.get_source(environment, name)
  File "C:\Users\john\webdev\google\lib\jinja2\jinja2\loaders.py", line 162, in get_source
    pieces = split_template_path(template)
  File "C:\Users\john\webdev\google\lib\jinja2\jinja2\loaders.py", line 33, in split_template_path
    raise TemplateNotFound(template)
TemplateNotFound: C:\Users\john\webdev\workspace\codemywayout\themes\default\admin\index.html
4

2 回答 2

1

我希望您不要尝试从与静态文件相同的路径加载 Jinja 模板

静态文件:模板/\1/静态/\2

因为您的应用程序无法访问该路径。

我会尝试记录 Jinja 尝试从中加载模板的路径,以帮助您了解它尝试加载模板的位置。

于 2012-06-10T02:15:26.837 回答
0

如果您查看 C:\Users\john\webdev\google\lib\jinja2\jinja2\loaders.py 第 33 行,您可能可以设置一个 pdb 断点import pdb; pdb.set_trace( )并查看发生了什么。

我在 Mac 上使用 SDK 源代码分发,但如果您的代码与我看到的相同,则为:

def split_template_path(template):
    """Split a path into segments and perform a sanity check.  If it detects
    '..' in the path it will raise a `TemplateNotFound` error.
    """
    pieces = []
    for piece in template.split('/'):
        if path.sep in piece \
           or (path.altsep and path.altsep in piece) or \
           piece == path.pardir:
            raise TemplateNotFound(template)
        elif piece and piece != '.':
            pieces.append(piece)
    return pieces

请注意for piece in template.split('/')它在 '/' 而不是path.sep. 我怀疑您的输入是 C:\Path\to\file.html 在这种情况下,片段是整个路径,adn path.sep(Windows 上的 \)确实是片段,这会产生 TemplateNotFound 错误。

而不是template_name = os.path.join("admin", template_name)你可以尝试template_name = 'admin/%s' % template_name,不要在 template_path 中包含 template_name 并将 template_name 而不是 template_pathenv.get_template(template_name, template_vals or {})作为 loaders.py 第 162 行表示它在 template_path 中查找 template_name

您的代码经过修改但未经测试看起来像

from google.appengine.ext import db
import webapp2
import jinja2
import os
import fix_path
import config


def render_template(template_name, template_vals=None, theme=None):
    template_path = os.path.join(os.path.dirname(__file__) , \
            "themes", theme or config.theme)
    env = jinja2.Environment(
        loader=jinja2.FileSystemLoader(template_path))
    return env.get_template(template_name, template_vals or {})

class BlogPost(db.Model):
    title = db.StringProperty()
    body = db.StringProperty()

def render(self):
    template_vals = {
        'config': config,
        'post': self,
    }
    return render_template("post.html", template_vals)

class BaseHandler(webapp2.RequestHandler):
    def render_to_response(self, template_name, \
            template_vals=None, theme=None):
        template_name = "admin/%s" % template_name
        self.response.out.write(render_template(template_name,\
            template_vals, theme))

class AdminHandler(BaseHandler):
    def get(self):
        greet = "hello"
        template_vals = {
            'greet': greet
        }
        self.render_to_response("index.html", template_vals)
于 2012-06-05T21:25:38.567 回答