【问题标题】:Django site using mod_wsgi on AWS cannot create FK form field because related model has not been loaded yet在 AWS 上使用 mod_wsgi 的 Django 站点无法创建 FK 表单字段,因为尚未加载相关模型
【发布时间】:2012-03-30 21:28:17
【问题描述】:

我正在开发一个 Django 站点,使用 Django 1.4 官方版本。我的网站有一些应用程序。其中一个应用程序有一个名为 Campaign 的模型,并具有其他应用程序中模型的 FK。正如 Django 参考 (https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey) 中所建议的,我选择使用字符串而不是相关模型类本身,因为我希望在下一个版本左右有循环引用,这种方法避免了循环导入问题。

当我使用 BitNami djangostack 1.4(Apache、mod_wsgi、MySQL)在 AWS(亚马逊网络服务)上部署站点时,我部署的站点在大多数情况下都能正常工作。在显示Campaign 模型的表单的页面上,Django 在尝试创建依赖于Campaign 模型的外键字段的表单字段时引发异常,抱怨未加载相关模型。有趣/可怕的是,当我将 settings.DEBUG 设置为 True 时(一旦网站上线,我们肯定不会想要的东西),问题就不再发生了!

当我在本地 Django 开发服务器上对其进行测试时,该站点运行良好,并且使用部署在我的 Windows 工作站上的同一个 BitNami djangostack 也运行良好。

这是我在 AWS 控制台上看到的相关 Apache 错误输出。

[error] ERROR :: Internal Server Error: /campaigns/
[error] Traceback (most recent call last):
[error]   File "/opt/bitnami/apps/django/lib/python2.6/site-packages/django/core/handlers/base.py", line 101, in get_response
[error]     request.path_info)
    ... (django/wsgi blah blah)
[error]   File "/opt/bitnami/apps/django/django_projects/Project/campaign/views.py", line 5, in <module>
[error]     from forms import CampaignForm
[error]   File "/opt/bitnami/apps/django/django_projects/Project/campaign/forms.py", line 12, in <module>
[error]     class CampaignForm(forms.ModelForm):
[error]   File "/opt/bitnami/apps/django/lib/python2.6/site-packages/django/forms/models.py", line 206, in __new__
[error]     opts.exclude, opts.widgets, formfield_callback)
[error]   File "/opt/bitnami/apps/django/lib/python2.6/site-packages/django/forms/models.py", line 160, in fields_for_model
[error]     formfield = f.formfield(**kwargs)
[error]   File "/opt/bitnami/apps/django/lib/python2.6/site-packages/django/db/models/fields/related.py", line 1002, in formfield
[error]     (self.name, self.rel.to))
[error] ValueError: Cannot create form field for 'reward' yet, because its related model 'reward.Reward' has not been loaded yet

所以,这里有一个快速回顾:

  1. 无论 settings.DEBUG 值如何,我的站点都可以在本地 Django 开发服务器上运行
  2. 在我的本地 Windows 机器上使用 BitNami 堆栈,无论 settings.DEBUG 值如何,它都能正常工作
  3. 使用 AWS (Ubuntu) 上的 BitNami 堆栈,它适用于 DEBUG = True 但不适用于 DEBUG = False

我理解错误的含义什么,但我不明白为什么它会发生,即为什么没有加载依赖模型。有没有人遇到过类似的问题,或者有什么建议可以帮助我解决它?

注意:我尝试用 Google 搜索错误消息,但我发现的只是引发该错误的 Django 源代码。我还尝试搜索更一般的查询,例如 mod_wsgi django related model,但我找不到任何与我的问题相关的内容。

【问题讨论】:

  • INSTALLED_APPS中是否包含相关模型的应用程序?
  • 是的,我网站的所有应用都在INSTALLED_APPS。应用程序的顺序重要吗?
  • 我在谷歌搜索时发现的链接之一是blog.dscpl.com.au/2010/03/…。我不确定它是否对我有帮助,但我会看看它。
  • @mbargiel 那个链接救了我!非常感谢!

标签: django amazon-web-services mod-wsgi


【解决方案1】:

好的,我在 Graham Dumpleton 的博客文章中找到了解决问题的方法 (http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html) .

简而言之,Django 开发服务器在启动时验证模型(它解析基于字符串的关系),并且在 DEBUG = False 的 Ubuntu 上使用 BitNami djangostack 下的 mod_wsgi 时可能没有完成该操作。非常具体的条件,我知道 - 但 G. Dumpleton 的“固定”mod_wsgi 代码为我解决了这个问题。

这就是我的 wsgi.py 现在的样子:

#wsgi.py

#make sure the folder containing the apps and the site is at the front of sys.path
#maybe we could just define WSGIPythonPath in django.conf file...?
project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) 
if project_root not in sys.path:
    sys.path.insert(0, project_root)

#set the DJANGO_SETTINGS_MODULE environment variable (doesn't work without this, despite what G. Dumpleton's blog post said)
site_name = os.path.basename(os.path.dirname(__file__))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "%s.settings" % site_name)

#new code - fixes inter-app model dependencies
from my_site import settings
import django.core.management
django.core.management.setup_environ(settings)  # mimic manage.py
utility = django.core.management.ManagementUtility()
command = utility.fetch_command('runserver')
command.validate()  # validate the models - *THIS* is what was missing

#setup WSGI application object
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

【讨论】:

  • 不幸的是,我遇到了同样的问题,但是在我的情况下,当我将 DEBUG 设置为 True 时会发生这种情况。你的 wsgi.py 不在我的实例上工作。 Here is django 代码中引发异常的一行。
  • 此解决方案也适用于 Heroku,如果人们在部署时遇到问题并遇到相同的错误。
【解决方案2】:

我遇到了这个问题,正在考虑按照建议修改 wsgi.py。然后一位同事建议简单地重新排序 INSTALLED_APPS 中的应用程序,嘿,不用接触 wsgi.py,它就可以工作了。

【讨论】:

  • 如果您能指出您如何重新订购它们以解决问题,那就太好了,即移动解决问题的应用程序。我相信它可以帮助其他面临同样问题的人。
  • 所以,错误是'Cannot create form field for 'xyz' yet, because its related model 'abc' has not been loaded'.我只是将包含 abc 的应用移到包含 xyz 的应用之前。
  • 我认为您的问题与我的不同(尽管症状相似)。我的问题是,在特定环境下,它仅在 settings.DEBUG 设置为 True 时才有效,因此很明显,这不是应用程序订购问题。最后,我发现 wsgi 包装器并不总是在启动时验证模型(取决于 DEBUG),因此尝试导入依赖于来自不同应用程序的模型的模型失败了,因为我的应用程序模型根本没有被解析(无论 INSTALLED_APPS 顺序如何)。这就是为什么我的解决方法是在我的 wsgi.py 中显式添加模型验证。
猜你喜欢
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多