【问题标题】:Google App Engine - Django - Python - Ubuntu - ProblemsGoogle App Engine - Django - Python - Ubuntu - 问题
【发布时间】:2014-10-26 03:24:35
【问题描述】:

我正在阅读“Head First Python”。我在介绍 Google App Engine 的第 10 章。最初使用 Python 和 Google App Engine 的 hello world 是成功的,但随后的程序都失败了。

我有以下 app.yaml 文件:

application: three
version: 1
runtime: python27
api_version: 1
threadsafe: false

handlers:
- url: /.*
  script: page368b.py

libraries:
- name: django
  version: "1.3"

使用以下 Python 代码(page368b.py):

import wsgiref.handlers

from google.appengine.ext import webapp
from google.appengine.ext import db
from google.appengine.ext.webapp import template

#this line throws the error when accessing the web-page 
from google.appengine.ext.db import djangoforms

import birthDB

class BirthDetailsForm(djangoforms.ModelForm):
    class Meta:
        model = birthDB.BirthDetails

class SimpleInput(webapp.RequestHandler):
    def get(self):
        html = template.render('templates/header.html', {'title': 'Provide your birth details'})
        html = html + template.render('templates/form_start.html', {})
        html = html + str(BirthDetailsForm(auto_id=False))     
        html = html + template.render('templates/form_end.html', {'sub_title': 'Submit Details'})
        html = html + template.render('templates/footer.html', {'links': ''})
        self.response.out.write(html)

def main():
    app = webapp.WSGIApplication([('/.*', SimpleInput)], debug=True)
    wsgiref.handlers.CGIHandler().run(app)

if __name__ == '__main__':
    main()

这是另一个导入到上面的名为birthDB.py的Python模块:

from google.appengine.ext import db

class BirthDetails(db.Model):
    name =          db.StringProperty()
    date_of_birth = db.DateProperty()
    time_of_birth = db.TimeProperty()

上面的 Python 模块调用了一个 templates 文件夹。他们有 HTML 代码和一些 Django 代码。这是一个使用 footer.html 的示例。

<p>
{{ links }}
</p>
</body>
</html>

其他 HTML 文件类似。我可以使用 BASH 中的以下命令毫无问题地启动 Google App Engine:python google_appengine/dev_appserver.py ~/Desktop/three 目录 three 包含 templates 文件夹,即 app.yaml 文件,上面显示的 Python 模块。

我的问题是当我访问http://localhost:8080 的网页时,什么都没有,运行命令以启动它的 BASH shell 显示了 Python 程序中导致问题的所有调用,然后最后说:ImportError:无法导入设置,因为环境变量 DJANGO_SETTINGS_MODULE 未定义。

我在几个不同的地方读到了一些不同的东西可以尝试,所以我想我会继续写一篇新的帖子,希望一些专业的 Python 程序员会插手进来,帮助像我这样迷失的霍比特人.

此外,书中说要安装 Python2.5 以使用此代码,但 Google App Engine 现在支持 Python2.7,而在本书写作之时还不可用。此外,我刚刚检查过,Python2.5 甚至不是与 Google App Engine 一起使用的选项。 Python2.5 deprecated

这可能太复杂了,无法在这里解决。 Head First Python 书中使用了所有这些不同的技术,我很惊讶。它要求很多 Python 菜鸟。 ^_^

问候,

user_loser

更新 - 我在我的 Ubuntu 操作系统上安装了 Django

当我将 python 模块 368b.py from google.appengine.ext.db import djangoforms 中的行更改为 from django import forms 时,在访问 localhost 上的网页时,我在控制台上收到以下错误:

loser@loser-basic-box:~/Desktop$ google_appengine/dev_appserver.py three
INFO     2014-09-06 21:08:36,669 api_server.py:171] Starting API server at:       http://localhost:56044
INFO     2014-09-06 21:08:36,677 dispatcher.py:183] Starting module "default" running at:   http://localhost:8080
INFO     2014-09-06 21:08:36,678 admin_server.py:117] Starting admin server at:  http://localhost:8000
ERROR    2014-09-06 21:08:48,942 cgi.py:121] Traceback (most recent call last):
File "/home/loser/Desktop/three/page368b.py", line 13, in <module>
class BirthDetailsForm(forms.ModelForm):
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/models.py", line  205, in __new__
opts.exclude, opts.widgets, formfield_callback)
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/models.py", line 145, in fields_for_model
opts = model._meta
AttributeError: type object 'BirthDetails' has no attribute '_meta'

INFO     2014-09-06 21:08:48,953 module.py:652] default: "GET / HTTP/1.1" 500 -
ERROR    2014-09-06 21:08:49,031 cgi.py:121] Traceback (most recent call last):
File "/home/loser/Desktop/three/page368b.py", line 13, in <module>
class BirthDetailsForm(forms.ModelForm):
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/models.py", line  205, in __new__
 opts.exclude, opts.widgets, formfield_callback)
 File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/models.py", line 145, in fields_for_model
opts = model._meta
 AttributeError: type object 'BirthDetails' has no attribute '_meta'

在不做任何更改的情况下运行程序更新错误:

loser@loser-basic-box:~/Desktop$ google_appengine/dev_appserver.py  three/
INFO     2014-09-06 21:35:19,347 api_server.py:171] Starting API server at:   http://localhost:60503
INFO     2014-09-06 21:35:19,356 dispatcher.py:183] Starting module "default" running at:  http://localhost:8080
INFO     2014-09-06 21:35:19,358 admin_server.py:117] Starting admin server at: http://localhost:8000
ERROR    2014-09-06 21:35:25,011 cgi.py:121] Traceback (most recent call last):
File "/home/loser/Desktop/three/page368b.py", line 13, in <module>
class BirthDetailsForm(djangoforms.ModelForm):
File "/home/loser/Desktop/google_appengine/google/appengine/ext/db/djangoforms.py", line  772, in __new__
form_field = prop.get_form_field()
File "/home/loser/Desktop/google_appengine/google/appengine/ext/db/djangoforms.py", line 370, in get_form_field
return super(DateProperty, self).get_form_field(**defaults)
File "/home/loser/Desktop/google_appengine/google/appengine/ext/db/djangoforms.py", line 353, in get_form_field
return super(DateTimeProperty, self).get_form_field(**defaults)
File "/home/loser/Desktop/google_appengine/google/appengine/ext/db/djangoforms.py", line 200, in get_form_field
return form_class(**defaults)
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/fields.py", line 340, in __init__
super(DateField, self).__init__(*args, **kwargs)
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/fields.py", line 99, in __init__
widget = widget()
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/widgets.py", line 382, in __init__
self.format = formats.get_format('DATE_INPUT_FORMATS')[0]
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/utils/formats.py", line 67, in get_format
if use_l10n or (use_l10n is None and settings.USE_L10N):
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/utils/functional.py", line 276, in __getattr__
self._setup()
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/conf/__init__.py", line 40, in _setup
raise ImportError("Settings cannot be imported, because environment variable %s is undefined." % ENVIRONMENT_VARIABLE)
ImportError: Settings cannot be imported, because environment variable  DJANGO_SETTINGS_MODULE is undefined.

【问题讨论】:

  • 你把 settings.py 文件放在哪里了?
  • 这是一个示例设置(不是我的):django-rocket-engine.readthedocs.org/en/latest/…
  • @power 没有 settings.py - 是的,我已经阅读过这个文件,但书中的示例中没有包含该文件。但是这本书是在 Python2.5 还在 Google App Engine 中使用的时候写的。
  • @power 关于火箭引擎的有趣教程...安装 Google App Engine 时,它​​带有 Django 1.2-1.5。当在文件夹中四处挖掘时,这一点很明显:google_appengine/lib/ 考虑到这一点,我认为我不需要在我的机器上安装我自己的 django 版本。另外,我需要留在 Google App Engine 沙箱中。你好。 0_o
  • 这个文件是由 'django-admin.py startproject' 命令生成的。请确保您已正确运行它。

标签: python django google-app-engine python-2.7 ubuntu


【解决方案1】:

我假设您正在使用本书随附的示例代码,可从以下网站获取:http://examples.oreilly.com/0636920003434/

如果您下载并展开第 10 章存档 (chapter10.zip),您将看到几个示例文件,以及多个 .zip 存档。 page368b.py 文件对应于 webapp-chapter10-simpleform.zip 存档。打开该存档以创建 webapp-chapter10-simpleform 目录。该目录包含app.yaml 文件、simpleform.py 文件(与page368b.py 相同)、birthDB.pyext.db 模型类)以及静态和模板文件目录。

很遗憾,您可能已经注意到,该示例不适用于最新的 SDK。 (我使用的是刚刚发布的 SDK 1.9.10 版。)当您尝试加载页面时,它会报告“ImportError: No module named django.core.exceptions”。严格来说,这个示例不是一个 Django 应用程序,而只是尝试使用一个依赖于 Django 存在的库。

Python 2.5 运行时环境(由本示例中包含的 app.yaml 文件选择)默认包含 Django 0.96。但是,自从 Head First Python 编写后,SDK 中的这种行为发生了变化。使该示例正常工作的最小修复方法是在导入 djangoforms 之前将这些行添加到 simpleform.py

import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

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

然后在您的应用程序根目录(webapp-chapter10-simpleform 目录)中创建一个名为 settings.py 的文件。在这种情况下,该文件可以为空。 (正如其他评论者所指出的,使用 Django 框架时有更好的方法来生成此文件,但在这种情况下,我们只需要导入成功即可。)


要将此示例升级为使用 Python 2.7 运行时环境,请将app.yaml 修改如下:

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

handlers:
- url: /static
  static_dir: static

- url: /*.
  script: simpleform.app

变化:

  • runtime: 现在是 python27
  • 已添加threadsafe: true
  • simpleform.py 的引用现在是全局变量app 的Python 对象路径。

然后修改simpleform.py,使SimpleInput类定义之后的所有内容都替换为:

app = webapp.WSGIApplication([('/.*', SimpleInput)], debug=True)

Python 2.7 运行时环境将其作为模块导入,而不是运行simpleform.py 脚本,然后在全局变量中查找 WSGI 应用程序对象。我们删除的行执行了应用程序,现在由运行时环境为我们完成。

如果您愿意,您可以从这里使用libraries: 子句来选择更新版本的 Django。在开发服务器中进行的快速测试表明,修改后的示例适用于 Django 1.5,这是支持的最新版本。

【讨论】:

  • 这个例子的另一个有点过时的方面是使用ext.db 库。如果您想在完成本章后进一步了解这一点,您可能需要查看 ndb 库,该库也包含在 App Engine 中并在 App Engine 官方文档中进行了描述。不过,没有更多内置的djangoforms 支持。 developers.google.com/appengine/docs/python/ndb
  • 另外值得注意的是:App Engine SDK 将使用它自己的 Django 版本,而不是您安装在 Ubuntu 机器上的那个。 SDK 包括支持的 Django 版本。 (我不知道以后的版本是否会这样。)
  • 感谢丹的帮助!这适用于我的机器。我现在可以看到第 369 页上的表格。您是 Python + Google App Engine 的大师。另外,我可以像你一样在谷歌工作吗?再次感谢您接听我的 Python 编码赏金的电话。:D
猜你喜欢
  • 2011-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多