正如Nick在systempuntoout答案的评论中所描述的,我插入了use_library()
code从这里在每个导入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)。
然而,我已经配置了内置的appstats,如果我在上传后第一次转到/\ah/appstats,那么我会收到以下错误:
< google.appengine.dist._library.UnacceptableVersionError >:
django 1.2 was requested, but
0.96.4.None is already in use
我还通过在appengine_config.py
中包含use_library()
代码来解决这个问题。
我注意到,通过在appengine_config.py
中插入对use_library()
的调用,在我的所有处理程序中都不再需要它。特别是那些导入google.appengine.ext.webapp.template
的应用程序不需要它,因为导入webapp.template
会加载appengine_config.py
。appstats UI导入webapp.tmplate
,这就是解决该问题的原因。
然而,我有一些处理程序(例如json服务),它们不导入webapp.template
,而是导入django.utils.simplejson
。这些处理程序仍然需要直接调用use_library()
。否则,如果在新实例上首先调用这些处理程序,则会出现AcceptableVersionError
。尽管我使用appengine_config.py
来配置appstats,这意味着调用appngine_connfig.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时,我出现了以下错误:
模板Does不存在:/页面基准.html
Django 1.2中的变化似乎是,默认情况下,Django不允许加载原始模板目录之上的模板。
有关此问题的解决方法,请参见此处,但这种方法对我来说不起作用,因为它要求模板位于templates子目录中。
解决方案是设置settings.py
文件,将TEMPLATE_DIRS
设置设置为项目根目录,然后将extends
标记更改为仅引用“page_base.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
设置,我在项目中添加了设置.py
:
PROJECT_ROOT = os.path.dirname(__file__)
TEMPLATE_DIRS = (PROJECT_ROOT,)
然后,在我的所有处理程序中,在use_library()
代码之前,我设置DJANGO_SETTINGS_MODULE
如此处所述:
import os
os.environ[ DJANGO_SETTINGS_MODULE ] = settings
第二个问题是这不起作用-设置文件没有加载,因此TEMPLATE_DIRS
为空。
Django设置是从指定的<code>settings.py</code>中加载的,第一次访问时会延迟加载。问题是导入webapp.template
会调用django.conf.settings.config()
来尝试设置一些设置。因此,如果在访问任何设置之前导入webapp.template
,则永远不会加载settings.py
(因为设置访问器发现设置已经存在,并且不再尝试加载)。
解决方案是在导入webapp.template
之前,强制访问设置,加载settings.py
。然后,当稍后导入webapp.template
时,将忽略其对django.conf.settings.config()
的调用。因此,我将所有处理程序(以及<code>appengine_config.py</code>)中的Django版本设置代码更改为以下代码:
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
模板,将其包括在内(即相对于template_DIRS
设置指定page_base.html
{% extends "page_base.html" %}
这修复了呈现管理页面的问题。