App引擎默认Django版本更改

时间:2011-02-14 17:01:47

标签: google-app-engine django-templates

自从app engine 1.4.2发布以来,我在生产日志中收到类似警告:

  

您正在使用默认的Django   版本(0.96)。默认的Django   版本将在App Engine中更改   在不久的将来发布。请   调用use_library()来显式地   选择一个Django版本。更多   信息见   http://code.google.com/appengine/docs/python/tools/libraries.html#Django

这发生在我使用Django模板的每个处理程序上 - 通过以下内容:

from google.appengine.ext.webapp import template

我想升级到1.2,但以下链接似乎并不清楚如何做到这一点(或者它是否有效):

共同点是插入:

from google.appengine.dist import use_library
use_library('django', '1.2')

但是,应插入哪个文件:

  1. 只是在appengine_config.py?
  2. 在每个执行from google.appengine.ext.webapp import template?。
  3. 的.py文件中
  4. 在项目的每个.py文件中?
  5. 在上面的1和(2或3)中,还将import appengine_config添加到这些文件中?
  6. 在3或4中,还可以在appstats,remote api,datastore admin等内置函数周围添加包装器?
  7. 别的什么?
  8. 感谢。

4 个答案:

答案 0 :(得分:56)

正如Nick在systempuntoout的回答中所描述的那样,我在每个导入django的处理程序中插入了use_library()代码from here(直接或通过google.appengine.ext.webapp.template甚至只是{{1} }}):

django.utils.simplejson

正如尼克所建议的那样,通过首次重构来减少app.yaml引用的处理程序数量(即接近scenario 1 described here),这一过程变得更容易了。

但是,我已经内置配置appstats,如果我在上传后第一次去/ _ah / appstats,那么我会收到此错误:

  

< 'google.appengine.dist._library.UnacceptableVersionError' 计算值:   请求django 1.2,但是   0.96.4。尚未使用

我能够通过在from google.appengine.dist import use_library use_library('django', '1.2') 中添加use_library()代码来解决此问题。

我注意到,通过在appengine_config.py中插入对use_library()的调用,我的所有处理程序都不再需要了。特别是导入appengine_config.py的人不需要它,因为导入google.appengine.ext.webapp.template会加载webapp.template。 appstats UI导入appengine_config.py,这就是解决此问题的原因。

但是,我有一些处理程序(例如json服务)不导入webapp.template,但导入webapp.template。这些处理程序仍需要直接调用django.utils.simplejson。否则,如果在新实例上首先调用这些处理程序,则会发生use_library()。虽然我使用UnacceptableVersionError来配置appstats,意味着appengine_config.py被调用以检测所有请求,但在页面生命周期中调用它太晚才能正确配置Django的正确版本。

这一切看起来一切正常,但后来我发现新Django 1.2和我一直在使用的旧Django 0.96之间的向后不兼容。我的项目结构是这样的:

appengine_config.py

使用Django 0.96,在page_admin.html中有以下内容正常工作:

root
+- admin
|  +- page_admin.html
+- page_base.html

使用Django 1.2,我收到了这个错误:

  

TemplateDoesNotExist:../ page_base.html

Django 1.2的变化似乎是默认情况下,Django不允许加载原始模板目录之上的模板。

对此进行了解决方法here,但这种方法对我来说无效,因为它需要模板位于模板子目录中。

解决方案是设置{% extends "../page_base.html" %} 文件,将settings.py设置设置为项目根目录,然后将TEMPLATE_DIRS标记更改为仅引用{{1} },described here。但是,我试图做到这两个问题。

我使用recommended code渲染我的模板,即:

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

然后在我的所有处理程序中,在settings.py代码之前,我设置了PROJECT_ROOT = os.path.dirname(__file__) TEMPLATE_DIRS = (PROJECT_ROOT,) as described here

use_library()

第二个问题是这不起作用 - 设置文件没有加载,因此DJANGO_SETTINGS_MODULE为空。

Django设置是在第一次访问时从懒惰的指定import os os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' 加载的。问题是导入TEMPLATE_DIRS调用settings.py以尝试设置某些设置。因此,如果在访问任何设置之前导入webapp.template,则永远不会加载django.conf.settings.configure()(因为设置访问者发现设置已存在,并且不再尝试加载)。

解决方法是在导入webapp.template之前强制访问设置,加载settings.py。然后,稍后导入settings.py时,将忽略对webapp.template的调用。因此,我将所有处理程序(和webapp.template)中的Django版本设置代码更改为以下内容:

django.conf.settings.configure()

实际上,我实际上将所有上述代码放在一个名为appengine_config.py的文件中,然后从我的所有处理程序中导入,而不是在任何地方复制这6行代码。

然后我更新了我的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设置指定page_admin.html):

page_base.html

这解决了呈现管理页面的问题。

答案 1 :(得分:17)

从GAE 1.5.0开始,指定您想要使用哪个版本的Django模板的方法要简单得多,但却暂时未充分记录。

appengine_config.py中,加上

webapp_django_version = '1.2'

就是这样。

不再需要use_library()

答案 2 :(得分:3)

根据您正确链接的documentation,您应该只在main.py脚本处理程序的开头添加此函数。

答案 3 :(得分:2)

有一件事我想提及documentation并不明确:如果您在use_library中使用google.appengine.ext.deferred并拥有main.py,那么延迟任务已执行它将不会加载main.py如果您不幸将延迟任务作为对实例的第一个请求,它将使实例生效(导致它抛出{ {1}} UnacceptableVersionError尝试在以后的请求中致电main.py时{1}}我认为如果您将use_library添加到appengine_config.py,它也可以与use_libary一起使用,但我们最终切换到常规任务队列(处理程序通过deferred路由)到避免这个问题。