Скрипт Django для доступа к объектам модели без использования команды manage.py
Я пишу скрипт для импорта некоторых объектов модели в базу данных, которую использует мое приложение django. В прошлом я решил это, запустив ./manage.py shell
а потом import myscript
, Я уверен, что есть лучший способ. Я хотел бы иметь возможность вызывать сценарий из любого места на моем HD с помощью python scriptname.py
и в первых нескольких строках этого скрипта он будет выполнять все необходимые операции импорта / других операций, чтобы он мог обращаться к объектам модели и вести себя так, как будто он был запущен с использованием manage.py shell
,
Что мне нужно добавить в мой сценарий, чтобы добиться этого?
РЕДАКТИРОВАТЬ:
Основываясь на ответе @Melug, с добавлением динамической установки пути Python для решения части вопроса "где угодно на моем HD":
import sys
sys.path.append('c:\\my_projec_src_folder')
from myproject import settings
from django.core.management import setup_environ
setup_environ(settings)
13 ответов
Сначала вам нужно настроить среду django:
from your_project import settings
from django.core.management import setup_environ
setup_environ(settings)
Наконец, импортируйте ваши модели, все идет так же, как в Django.
Начиная с Django 1.4, вам следует избегать использования setup_environ(settings)
(сообщение от Melug), потому что это устарело. Используйте следующее вместо этого, и вы сможете получить доступ к вашей модели
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project_name.settings")
# your imports, e.g. Django models
from your_project_name.models import Location
# From now onwards start your script..
Вот пример для доступа и изменения вашей модели:
if __name__ == '__main__':
# e.g. add a new location
l = Location()
l.name = 'Berlin'
l.save()
# this is an example to access your model
locations = Location.objects.all()
print locations
# e.g. delete the location
berlin = Location.objects.filter(name='Berlin')
print berlin
berlin.delete()
Пример модели:
class Location(models.Model):
name = models.CharField(max_length=100)
Чтобы загрузить модели тоже, мне пришлось объединить это с этим ответом, в противном случае я получаю django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings")
import django
django.setup()
В качестве дополнения, я добавляю это к __init__.py
из моих проектов django, он автоматически обнаружит имя приложения, поэтому его можно копировать / вставлять:
import os
def setup():
module = os.path.split(os.path.dirname(__file__))[-1]
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{}.settings".format(module))
import django
django.setup()
Тогда я могу просто сделать:
from <app> import setup
setup()
Для Django версии 1.9 или выше вы можете использовать это:
import sys
import os
import django
sys.path.append('your_project_directory')
os.environ['DJANGO_SETTINGS_MODULE'] = 'your_project.settings'
django.setup()
from yourapp.models import your_model
так что вы можете использовать объект как тот же объект django:
from myapp.models. import Locations
all_locations = Locations.object.all()
first_location = Locations.object.get(id=1)
print first_location.name()
first_location.save()
Я думаю, что лучший способ - это создать ваши собственные команды управления. Тогда вы можете позвонить manage.py <yourcommand>
откуда угодно.
ДЛЯ ДЖАНГО 1.11
Верхние решения не сработали, но выдало ошибку:
django.core.exceptions.AppRegistryNotReady: приложения еще не загружены.
Для меня решение здесь разработано:
import os
from django.core.wsgi import get_wsgi_application
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
application = get_wsgi_application()
Начиная с версии Django 1.11, ваше основное приложение включает в себя модуль wsgi, который выполняет необходимые настройки при импорте. Если предположить, myproject/myproject
где ваш файл settings.py, в вашем скрипте просто импортируйте:
from myproject.wsgi import application
Для django >= 2.0 достаточно сделать эти 2 импорта
from your_project_path import settings as your_project_settings
from django.core.management import settings
тогда ты можешь просто from my_app.models import MyModel
и работай со своей моделью MyModel
Если вы получаете:
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
Пытаться:
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')
application = get_wsgi_application()
Вот ответ для версий Django> 1.4:
from django.core.management import settings
from myproject.myproject import settings as project_settings
if not settings.configured:
settings.configure(default_settings=project_settings)
Пытаться:
os.environ["DJANGO_SETTINGS_MODULE"] = "mysite.settings"
если os.environ.setdefault
не работает (Windows 10, python3.6.4, django 2.0.3)
Как указывал здесь Ставрос, вы можете просто скопировать wsgi.py и поместить его в начало вашего скрипта. Помимо настройки DJANGO_SETTINGS_MODULE, вам также необходимо получить приложения. Надеюсь, поможет. У меня это работает на Django 2.1.5.
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'revochem.settings')
application = get_wsgi_application()
Многие из приведенных выше ответов верны, но не ссылаются на официальную документацию .
Сначала вам нужно настроить параметры или установить переменную окружения
from django.conf import settings
if not settings.configured:
settings.configure(myapp_defaults, DEBUG=True)
Затем в документах указывается:
После того, как вы установили
DJANGO_SETTINGS_MODULE
или позвонилconfigure()
вам нужно позвонить, чтобы загрузить настройки и заполнить реестр приложений Django. Например:import django from django.conf import settings from myapp import myapp_defaults settings.configure(default_settings=myapp_defaults, DEBUG=True) django.setup() # Now this script or any imported module can use any part of Django it needs. from myapp import models ```
Документы также включают важное предостережение:
django.setup()
может быть вызван только один раз.Поэтому избегайте размещения многократно используемой логики приложения в автономных скриптах, чтобы вам пришлось импортировать из скрипта в другое место вашего приложения. Если вы не можете избежать этого, поместите вызов django.setup() внутри блока if:
if __name__ == '__main__': import django django.setup()