正如尼克在 systempuntoout 的答案的评论中所描述的,我插入了这个use_library()
code 从这里 http://code.google.com/appengine/docs/python/tools/libraries.html#Django在每个导入 django 的处理程序中(直接或通过google.appengine.ext.webapp.template
甚至只是django.utils.simplejson
):
from google.appengine.dist import use_library
use_library('django', '1.2')
正如 Nick 所建议的,通过首先重构以最小化 app.yaml 引用的处理程序数量(即更接近于此处描述的场景 1 https://stackoverflow.com/questions/3025921/is-there-a-performance-gain-from-defining-routes-in-app-yaml-versus-one-large-map).
但是,我配置了内置的 appstats,如果我在上传后首先访问 /_ah/appstats,那么我会收到此错误:
:
请求了 django 1.2,但是
0.96.4.None 已在使用
我还可以通过包括来解决这个问题use_library()
代码在appengine_config.py
.
我注意到通过插入一个电话use_library()
in appengine_config.py
,那么在我的所有处理程序中就不再需要它了。特别是那些进口的google.appengine.ext.webapp.template
不需要它,因为导入webapp.template
loads appengine_config.py
。 appstats UI 导入webapp.template
,这就是为什么这解决了这个问题。
但是,我有一些不导入的处理程序(例如 json 服务)webapp.template
,但要导入django.utils.simplejson
。这些处理程序仍然需要直接调用use_library()
。否则,如果首先在新实例上调用这些处理程序,则UnacceptableVersionError
发生。虽然我正在使用appengine_config.py
配置appstats,含义appengine_config.py
被调用来检测所有请求,它在页面生命周期中被调用得太晚,无法正确配置正确的 Django 版本。
一开始这一切似乎都工作正常,但后来我发现新的 Django 1.2 和我一直使用的旧 Django 0.96 之间存在向后不兼容性。我的项目结构是这样的:
root
+- admin
| +- page_admin.html
+- page_base.html
对于 Django 0.96,在 page_admin.html 中包含以下内容可以正常工作:
{% extends "../page_base.html" %}
使用 Django 1.2,我收到此错误:
模板不存在:../page_base.html
Django 1.2 中的变化似乎是,默认情况下,Django 不允许加载原始模板目录之上的模板。
描述了此问题的解决方法here http://groups.google.com/group/google-appengine-python/browse_thread/thread/61aa9f7b282889a2/d0165683ddd0c82b,但这种方法对我来说不起作用,因为它要求模板位于 templates 子目录中。
解决这个问题的方法是设置一个settings.py
文件,设置TEMPLATE_DIRS
设置到项目根目录,然后更改extends
标记为仅供参考"page_base.html"
, as 此处描述 https://stackoverflow.com/questions/1957089/render-to-response-gives-templatedoesnotexist。然而,我在尝试这样做时遇到了两个问题。
我当时用的是推荐代码 http://code.google.com/appengine/docs/python/gettingstarted/templates.html渲染我的模板,即:
template_values = { ... }
path = os.path.join(os.path.dirname(__file__), 'page_admin.html')
self.response.out.write(template.render(path, template_values))
第一个问题是template.render()
覆盖TEMPLATE_DIRS
设置,将其设置为正在渲染的模板的目录。解决这个问题的方法是下面的代码:
template_values = { ... }
path = os.path.join(os.path.dirname(__file__), 'page_admin.html')
template_file = open(path)
compiled_template = template.Template(template_file.read())
template_file.close()
self.response.out.write(compiled_template.render(template.Context(template_values)))
但这种方法的一个缺点是template.render()
缓存已编译的模板,而此代码则不会(尽管添加并不难)。
要配置TEMPLATE_DIRS
设置,我添加了一个settings.py
到我的项目:
PROJECT_ROOT = os.path.dirname(__file__)
TEMPLATE_DIRS = (PROJECT_ROOT,)
然后在我所有的处理程序中,在use_library()
代码,我设置了DJANGO_SETTINGS_MODULE
如此处所述 http://code.google.com/appengine/docs/python/tools/libraries.html#Django:
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
第二个问题是这不起作用 - 设置文件没有加载,所以TEMPLATE_DIRS
是空的。
Django 设置从指定的位置加载settings.py
第一次访问它们时是懒惰的。问题是导入webapp.template
calls django.conf.settings.configure()
尝试设置一些设置。因此如果webapp.template
在访问任何设置之前导入,然后settings.py
永远不会加载(因为设置访问器发现设置已经存在,并且不再尝试加载)。
解决方案是强制访问设置,加载settings.py
, 前webapp.template
是进口的。那么当webapp.template
后来被导入,它的调用django.conf.settings.configure()
被忽略。因此,我更改了所有处理程序中的 Django 版本设置代码(以及appengine_config.py
)到以下内容:
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.dist import use_library
use_library('django', '1.2')
from django.conf import settings
_ = settings.TEMPLATE_DIRS
实际上,我实际上将上述所有代码放在一个名为setup_django_version.py
,然后从我的所有处理程序中导入它,而不是到处复制这 6 行代码。
然后我更新了我的page_admin.html
包含此内容的模板(即指定page_base.html
相对于TEMPLATE_DIRS
环境):
{% extends "page_base.html" %}
这解决了呈现管理页面的问题。