Как устранить неполадки - ImportError: Не удалось импортировать настройки «mysite.settings» при развертывании django? - PullRequest
3 голосов
/ 08 ноября 2011

Мое приложение django развернуто и отлично работает с apache и mod_python, согласно инструкциям по развертыванию apache.Но так как я несколько изменил структуру проекта, я не смог заставить его работать.Независимо от того, что я пытаюсь, я получаю следующую страницу:

MOD_PYTHON ERROR

ProcessId:      27841
Interpreter:    '127.0.0.1'

ServerName:     '127.0.0.1'
DocumentRoot:   '/var/www'

URI:            '/myapp/'
Location:       '/myapp/'
Directory:      None
Filename:       '/var/www/myapp'
PathInfo:       '/'

Phase:          'PythonHandler'
Handler:        'django.core.handlers.modpython'

Traceback (most recent call last):

  File "/usr/lib/python2.6/dist-packages/mod_python/importer.py", line 1537, in HandlerDispatch
    default=default_handler, arg=req, silent=hlist.silent)

  File "/usr/lib/python2.6/dist-packages/mod_python/importer.py", line 1229, in _process_target
    result = _execute_target(config, req, object, arg)

  File "/usr/lib/python2.6/dist-packages/mod_python/importer.py", line 1128, in _execute_target
    result = object(arg)

  File "/usr/local/lib/python2.6/dist-packages/Django-1.3.1-py2.6.egg/django/core/handlers/modpython.py", line 212, in handler
    return ModPythonHandler()(req)

  File "/usr/local/lib/python2.6/dist-packages/Django-1.3.1-py2.6.egg/django/core/handlers/modpython.py", line 174, in __call__
    self.load_middleware()

  File "/usr/local/lib/python2.6/dist-packages/Django-1.3.1-py2.6.egg/django/core/handlers/base.py", line 39, in load_middleware
    for middleware_path in settings.MIDDLEWARE_CLASSES:

  File "/usr/local/lib/python2.6/dist-packages/Django-1.3.1-py2.6.egg/django/utils/functional.py", line 276, in __getattr__
    self._setup()

  File "/usr/local/lib/python2.6/dist-packages/Django-1.3.1-py2.6.egg/django/conf/__init__.py", line 42, in _setup
    self._wrapped = Settings(settings_module)

  File "/usr/local/lib/python2.6/dist-packages/Django-1.3.1-py2.6.egg/django/conf/__init__.py", line 89, in __init__
    raise ImportError("Could not import settings '%s' (Is it on sys.path?): %s" % (self.SETTINGS_MODULE, e))

ImportError: Could not import settings 'settings' (Is it on sys.path?): No module named settings

Чтение различных потоков, проблема может быть одной из следующих

  • неверный файл конфигурации apache
  • неверный sys.path
  • неверные разрешения для любого файла или каталога
  • ошибки в коде моего сайта django

Есть ли способ сузить проблемунемного?Например, есть ли способ узнать, что такое sys.path во время ошибки?Есть ли какие-нибудь файлы журналов, которые могут помочь мне здесь?Есть ли способ различить «файл не найден» и «нет разрешения на чтение файла»?Я хотел бы подойти к решению более научно, чем просто пробовать случайные вещи, пока не наткнулся на решение.

Этот вопрос не совпадает с: Ошибка Mod_python: ImportError: Не удалось импортировать настройки .Я специально спрашиваю, как можно сузить возможные решения, а не сами решения.

Ответы [ 2 ]

7 голосов
/ 08 ноября 2011

Хорошо, я сам решил проблему, поэтому я отвечу на свой вопрос.Я обнаружил, что нет журнала apache или какого-либо другого источника информации, чтобы выяснить, что именно вызывает ошибку импорта.Итак, я поделюсь своим методом ниже, как более «рациональным» подходом, в надежде, что я смогу сэкономить кому-то несколько разочаровывающих часов случайных изменений.

Для справки, вот конфигурация apache, которую я использовал,

<Location "/mysite/">
    SetHandler python-program
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE mysite_django.settings
    PythonOption django.root /mysite
    PythonDebug On
    PythonPath "['/home/mysite/prg/mysite/mysite_django', '/home/mysite/prg/mysite'] + sys.path"
</Location>

Я создал пользователя «mysite» на сервере, и django settings.py находится в (несколько избыточно названном) месте /home/mysite/prg/mysite/mysite_django/settings.py.Я открываю канал SSH к серверу.В этом случае я использую очень полезную утилиту screen для быстрого переключения между пользователями (но второй канал ssh будет работать так же хорошо)

screen

Нажмите Ctrl-A, Ctrl-C, чтобы создать новыйэкран.Теперь важно видеть разрешения точно так, как это делает apache, поэтому я переключаюсь на пользователя, который запускает apache, то есть www-data в системах debian:

sudo -i -u www-data

Я собираюсь попытаться импортировать настройки.py себя из среды python:

python

>>> import os, sys
>>> print sys.path
... result omitted ...

Это, очевидно, должно дать вам стандартный sys.path без каких-либо каталогов "mysite", потому что мы работаем с простым python.Поэтому я изменил sys.path следующим образом.Я вставил копию прямо из конфигурации apache, чтобы избежать опечаток:

>>> sys.path = ['/home/mysite/prg/mysite/mysite_django', '/home/mysite/prg/mysite'] + sys.path
>>> import mysite_django.settings
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named mysite_django.settings

Как и ожидалось, я получаю ту же ошибку, которую уже видел при загрузке своего сайта в браузере.Так что я могу воспроизвести проблему в среде Python, это хорошо.Очевидно, что путь сборки должен быть сформирован из записи пути sys «/ home / mysite / prg / mysite» плюс запрошенный путь импорта «mysite_django / settings.py».Так почему же он не импортирует?Давайте удостоверимся, что данная запись sys path действительно существует

>>> os.path.exists (sys.path[0])
False

Она не существует?Странный.

>>> os.path.exists ('/home')
True
>>> os.path.exists ('/home/mysite')
True
>>> os.path.exists ('/home/mysite/prg/')
True
>>> os.path.exists ('/home/mysite/prg/mysite')
True
>>> os.path.exists ('/home/mysite/prg/mysite/mysite_django')
False

Здесь я понимаю, что с разрешениями mysite_django что-то не так.Вероятно, остаток от всех случайных изменений, которые я сделал.Но на самом деле проблема в каталоге выше, mysite, потому что именно здесь он пытается прочитать список каталогов.Я переключаюсь на экран суперпользователя с помощью Ctrl-A, Ctrl-N и использую chmod, чтобы установить разрешения для mysite таким образом, чтобы они совпадали с последним каталогом, который прошел успешно:

$ ls -la /home/mysite/prg
total 12
drwxr-xr-x 3 mysite mysite 4096 2011-11-08 11:24 .
drwxr-xr-x 7 mysite mysite 4096 2011-11-08 14:56 ..
drwxr-xr-- 6 mysite mysite 4096 2011-11-08 11:35 mysite
$ chmod o+x /home/mysite/prg/mysite/
$ ls -la /home/mysite/prg
total 12
drwxr-xr-x 3 mysite mysite 4096 2011-11-08 11:24 .
drwxr-xr-x 7 mysite mysite 4096 2011-11-08 14:56 ..
drwxr-xr-x 6 mysite mysite 4096 2011-11-08 11:35 mysite

Переключениевернуться к экрану www-данных с помощью Ctrl-A, Ctrl-N:

>>> os.path.exists ('/home/mysite/prg/mysite/mysite_django')
True
>>> os.path.exists ('/home/mysite/prg/mysite/mysite_django/settings.py')
True

Теперь для финального теста

>>> import mysite_django.settings
>>>

Yay!Успех Мы можем даже пойти дальше и проверить, что django может загрузить

>>> from django.core.management import setup_environ
>>> setup_environ(mysite_django.settings)
'/home/mysite/prg/mysite/mysite_django'

. В этот момент сайт снова работал в моем браузере.

Выполнив эти шаги, вы можете по крайней мере убедиться, что:

  • нет проблем с правами для settings.py для пользователя www-data
  • нет ошибок в настройке PythonPath вашей конфигурации apache
  • естьнет ошибок времени выполнения при импорте settings.py
2 голосов
/ 13 июня 2013

для моего Django 1.5 и mod_wsgi, я решил это так:

httpd.conf:

WSGIScriptAlias /mysite "/var/www/html/mysite/mysite/wsgi.py"
WSGIPythonPath  "/var/www/html/mysite/mysite"
<Directory "/var/www/html/mysite/mysite">
    Order deny,allow
    Allow from all
</Directory>

wsgi.py:
sys.path.append (путь), чтобы позволить mysite.settings известны

import os
import sys                                              #new
path = '/var/www/html/mysite'                           #new
if path not in sys.path:                                #new
    sys.path.append(path)                               #new

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

еще одна вещь, чтобы избежать ошибки, как показано ниже

Premature end of script headers: wsgi.py

вам нужно удалить cgi configure из httpd.conf

AddHandler cgi-script .py  
...