App Engine 默认 Django 版本更改

2023-12-22

自从 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 http://code.google.com/appengine/docs/python/tools/libraries.html#Django

这种情况发生在我使用 Django 模板的每个处理程序上 - 通过以下方式:

from google.appengine.ext.webapp import template

我想升级到 1.2,但是以下链接似乎不太清楚具体如何执行此操作(或者它是否有效):

  • http://code.google.com/appengine/docs/python/tools/libraries.html#Django http://code.google.com/appengine/docs/python/tools/libraries.html#Django
  • http://code.google.com/p/googleappengine/issues/detail?id=1758 http://code.google.com/p/googleappengine/issues/detail?id=1758
  • http://code.google.com/p/googleappengine/issues/detail?id=4489 http://code.google.com/p/googleappengine/issues/detail?id=4489
  • http://www.mediacrafters.org/post/django11-on-appengine http://www.mediacrafters.org/post/django11-on-appengine

共同的线程是插入以下内容:

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

但是,应该将其插入到哪个文件中:

  1. 就在 appengine_config.py 中吗?
  2. 在每个 .py 文件中from google.appengine.ext.webapp import template?
  3. 在项目中的每个 .py 文件中?
  4. 在上面的1和(2或3)中,还添加import appengine_config到那些文件?
  5. 在 3 或 4 中,还添加内置函数(如 appstats、远程 api、数据存储管理等)的包装器?
  6. 还有别的事吗?

Thanks.


正如尼克在 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" %}

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

App Engine 默认 Django 版本更改 的相关文章

随机推荐