Использование моделей Django во внешнем python script

Сегодня я был очень смущен.

Я пытаюсь использовать мои модели приложений django в своем python script.

вот мой подход

import os, sys

sys.path.append("/var/www/cloudloon/horizon")
os.environ["DJANGO_SETTINGS_MODULE"] = "openstack_dashboard.settings"
from django.contrib.auth.models import User

Я был в замешательстве, почему он дал мне

ImportError: Could not import settings 'openstack_dashboard.settings' (Is it on sys.path?): cannot import name auth

После проверки я создал файл с именем creds, который включает

export PYTHONPATH=$PYTHONPATH:/var/www/cloudloon/horizon/; 
export DJANGO_SETTINGS_MODULE=openstack_dashboard.settings; django-admin.py shell;

и из окна терминала, где находится файл creds, я делаю

source creds

и из этой оболочки django-admin.py я могу импортировать любую из моих моделей приложений django без каких-либо ошибок.

Почему это не работает в моем python script?

Я закончил с Django. Мне нужно создать python-daemon script, который будет обращаться к моим моделям приложений django.

Я работаю в Ubuntu 12.04, у которого есть django 1.5

Как я ищем решения, я сделал это:

import os, sys

sys.path.append("/var/www/cloudloon/horizon")
sys.path.append("/var/www/cloudloon/horizon/openstack_dashboard")
# os.environ["DJANGO_SETTINGS_MODULE"] = "settings"
os.environ.setdefault("DJANGO_SETTINGS_MODULE",
                          "openstack_dashboard.settings")

print os.environ["DJANGO_SETTINGS_MODULE"]
for s in sys.path:
    print s

from django.contrib.auth.models import User

выводит вывод: http://paste.openstack.org/show/48787/

как вы можете видеть, каталог, в котором находится settings.py, присутствует на моем sys.path, однако он все еще не смог импортировать openstack_dashboard.settings.

Спасибо всем.

Ответ 1

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

Создайте модуль под названием management (другими словами, создайте каталог management и внутри него создайте пустой файл __init__.py) внутри каталога любого приложения, которое вы указали в INSTALLED_APPS. Поэтому, если у вас есть myapp, вы должны создать:

myapp
 |
 > management
 | | __init__.py
 > models.py
 > views.py

Затем в каталоге управления создайте еще один модуль commands и в нем создайте файл, который является именем вашей команды; например my_command.py, например:

myapp
 |
 > management
 | | __init__.py
 | | commands
 | | | __init__.py
 | | | my_command.py
 > models.py
 > views.py

В my_command.py напишите этот шаблонный код:

from django.core.management.base import BaseCommand, CommandError
from myapp.models import MyModel

class Command(BaseCommand):
    help = 'Does some magical work'

    def handle(self, *args, **options):
        """ Do your work here """
        self.stdout.write('There are {} things!'.format(MyModel.objects.count()))

После сохранения файла вы сможете сделать python manage.py my_command, и он будет иметь доступ ко всем вашим моделям и настройкам.

Если вам нужно запустить его как демон, Daniel Roseman написал django-initd, который делает именно это. После его установки:

from django.core.management.base import CommandError
from daemon_command import DaemonCommand
from myapp.models import MyModel

class Command(DaemonCommand):
    help = 'Does some magical work'

    def loop_callback(self, *args, **options):
        """ Do your work here """
        self.stdout.write('There are {} things!'.format(MyModel.objects.count()))

Как только вы выполните из github readme:

The important parts of such a process are these:

    * it comes up automatically on server startup
    * it logs errors and information to a named location, which is configurable
    * if the process dies, it restarts itself straight away 

[...]

Run the command as normal, but pass one of --start, --stop or --restart to 
work as a daemon. Otherwise, the command will run as a standard application.

Ответ 2

Ниже script должно работать при условии, что макет вашего проекта (и путь к вашему файлу настроек) выглядит следующим образом:

/var/www/cloudloon/horizon/openstack_dashboard/settings.py

#!/usr/bin/env python
import os, sys

sys.path.append("/var/www/cloudloon/horizon")
os.environ["DJANGO_SETTINGS_MODULE"] = "openstack_dashboard.settings"
from django.contrib.auth.models import User

Я полагаю, что проблема, которую вы видите, связана с расположением вашего проекта или для добавления другого уровня каталога в вызов sys.path в script.

Edit:

Глядя на ваш проект github, horizon и openstack_dashboard находятся на одном уровне каталогов. То, что вы хотите сделать, - установить sys.path на один уровень выше:

sys.path.append("/var/www/cloudloon")