Сайт Django, использующий mod_wsgi в AWS, не может создать поле формы FK, потому что связанная модель еще не была загружена - PullRequest
4 голосов
/ 31 марта 2012

Я работаю над сайтом Django, используя официальный релиз Django 1.4. На моем сайте есть несколько приложений. У одного из приложений есть модель с именем Campaign с FK для моделей из других приложений. Как предложено в справочнике Django (https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey),), я решил определить поля FK, используя строку вместо самих классов связанных моделей, так как я ожидаю, что в следующей версии или около того будут циклические ссылки, и этот подход позволяет избежать проблем циклического импорта.

Когда я развернул сайт в AWS (Amazon Web Services) с использованием BitNami djangostack 1.4 (Apache, mod_wsgi, MySQL), мой развернутый сайт по большей части работал правильно. На страницах, отображающих формы для модели Campaign, Джанго выдвигал исключение при попытке создать поле формы, опираясь на поле внешнего ключа модели Campaign, жалуясь, что связанная модель не была загружена. Забавно / страшно то, что когда я установил settings.DEBUG в True (определенно не то, что нам нужно, когда сайт заработает), проблема больше не возникает!

Сайт работал отлично, когда я тестировал его на своем локальном сервере разработки Django, и он также отлично работал, используя тот же BitNami djangostack, развернутый на моей рабочей станции Windows.

Вот соответствующий вывод ошибок Apache, который я вижу на консоли AWS.

[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. Мой сайт работает на моем локальном сервере разработки Django, независимо от настроек. Значение отладки
  2. Со стеком BitNami на моем локальном компьютере с Windows он работает независимо от настроек. Значение отладки
  3. Со стеком BitNami в AWS (Ubuntu) он работает с DEBUG = True , но не с DEBUG = False

Я понимаю , что означает ошибку, но я не понимаю , почему это происходит, то есть почему не загружается зависимая модель. Кто-нибудь когда-либо сталкивался с подобной проблемой, или есть совет, который мог бы помочь мне исправить это?

Примечание. Я попытался отправить сообщение об ошибке в Google, но обнаружил только исходный код Django, в котором возникла эта ошибка. Я также попытался найти более общие запросы, например mod_wsgi django related model, но не смог найти ничего, что могло бы относиться к моей проблеме.

Ответы [ 2 ]

7 голосов
/ 02 апреля 2012

Хорошо, я нашел решение своей проблемы в посте Грэма Дамплтона (http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html).

). Короче говоря, сервер разработки Django проверяет модели (которые разрешают отношения на основе строк) при запуске, и эта операциявероятно, это не было сделано при использовании mod_wsgi под djangostack BitNami в Ubuntu с DEBUG = False. Я знаю, что это очень специфические условия, но «исправленный» код 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()
1 голос
/ 15 января 2014

У меня была только эта проблема, и я смотрел на изменение wsgi.py как предложено. Тогда коллега предложил просто переупорядочить приложения в INSTALLED_APPS, и, привет, это работает, не касаясь wsgi.py.

...