Как выполнить скрипт Python из оболочки Django?

247

Мне нужно выполнить скрипт Python из оболочки Django. Я попытался:

./manage.py shell << my_script.py

Но это не сработало. Просто ждал, что я что-нибудь напишу.

Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
источник
Это не так, как djangoработает, что вы на самом деле хотите сделать?
Данодонован
2
my_script.pyсодержит несколько операций над одной из моих моделей Django. Я уже делал это раньше, но не могу вспомнить, как именно.

Ответы:

388

<<Часть неправильна, используйте <вместо этого:

$ ./manage.py shell < myscript.py

Вы также можете сделать:

$ ./manage.py shell
...
>>> execfile('myscript.py')

Для python3 вам нужно использовать

>>> exec(open('myscript.py').read())
codeape
источник
17
Для меня это выполняет только первую строку скрипта. Единственное, что работает, - это объединение обоих методов:./manage.py shell <<EOF\ execfile('myscript.py') \EOF
Стив Беннетт
Это больше не работает с Python 3+. Есть идеи, чтобы заменить это?
Дэвид Д.
4
@DavidD. Замена дается в этом ответе здесь
peter2108
11
Другое решение, которое работает как для Python 2.x, так и для 3.x, - это echo 'import myscript' | python manage.py shell. Я обнаружил, что это может быть полезно для быстрых и грязных сценариев, которые нужно запускать только один раз, без необходимости выполнять трудоемкий процесс создания manage.pyкоманды.
Атул Варма
1
если вы делаете это на Windows Power Shell: Get-Content myscript.py | .\manage.py shell
Aditya Wirayudha
219

Вы не рекомендуется делать это из shell- и это предназначено , как вы не должны действительно быть выполнение случайных сценариев из среды Джанго (но есть способы обойти это, смотрите другие ответы).

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

 $ ./manage.py my_command

чтобы сделать это создать файл в подпапке managementи commandsиз вашего app, т.е.

my_app/
    __init__.py
    models.py
    management/
        __init__.py
        commands/
            __init__.py
            my_command.py
    tests.py
    views.py

и в этом файле определите свою пользовательскую команду (убедитесь, что имя файла - это имя команды, из которой вы хотите выполнить ./manage.py)

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    def handle(self, **options):
        # now do the things that you want with your models here
danodonovan
источник
9
Опять же, это лучший ответ. Поскольку django 1.8 NoArgsCommandустарела. На этой странице приведен рабочий пример: docs.djangoproject.com/en/1.9/howto/custom-management-commands/…
Ger
2
Согласно предыдущему комментарию, чтобы это работало на меня, мне нужно было перейти def handle_noargs(self, **options):на def handle(self, **options):.
Джеймс
Интересная ссылка здесь в поддержку этого ответа и документации.
Маттиа Патерна
1
Чтобы заставить его работать, измените на def handle(self, **options):комментарий Джеймса.
Омар Гонсалес
Элегантный ответ. Большое спасибо
Tessaracter
103

Для тех, кто использует Django 1.7+, кажется, что просто импортировать модуль настроек недостаточно.

После некоторого поиска я нашел ответ на переполнение стека: https://stackoverflow.com/a/23241093

Теперь вам нужно:

import os, django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
django.setup()
# now your code can go here...

Не делая выше, я получил django.core.exceptions.AppRegistryNoReadyошибку.

Мой файл скрипта находится в той же директории, что и мой проект django (т.е. в той же папке, что и manage.py)

cgons
источник
2
В моей настройке уже есть файл настроек, указанный в DJANGO_SETTINGS_MODULEпеременной окружения. С этим было достаточно просто: import django ; django.setup()под 1.7.
Тейлор Эдмистон
1
С django 1.7+ это должен быть принятый ответ :)
acidjunk
Это, безусловно, правильный ответ для Django 1.9.x. Не запускать django.setup()не позволит скрипт получить доступ к моделям Django, даже не импортировать их!
гларрей
В virtualenv вы можете просто import django; django.setup().
User3759685
1
Вы сделали мой день! Спасибо за этот пост. мне стало плохо на сельдерее, потому что я не смог выполнить задачи на менеджмент.call_command: D: D: D
68

Я опаздываю на вечеринку, но надеюсь, что мой ответ кому-нибудь поможет: вы можете сделать это в своем скрипте Python:

import sys, os
sys.path.append('/path/to/your/django/app')
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from django.conf import settings

остальная часть ваших вещей идет сюда ....

е-Ноури
источник
3
Также обратите внимание, что вы можете отбросить sys.path.appendматериал, если у вас все получится DJANGO_SETTINGS_MODULES(например, если у вас есть скрипт, расположенный прямо над корнем сайта, вы можете это сделать os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings').
mgalgs
Я закончил делать sys.path.append(os.getcwd()), это работает, когда я нахожусь в каталоге моего проекта, мой DJANGO_SETTINGS_MODULE правильный, и я пытаюсь запустить скрипт, который импортирует модели, виды и т. Д.
Данило Кабелло
да, но вы не можете запустить его из любого места!
e-nouri
Это не работает для меня с Django 1.6 - у меня есть приложение. Я установил свой путь, чтобы включить каталог проекта django и настроить параметры проекта. Но когда я пытаюсь импортировать свое приложение с помощью «из shoppinglist.models import ShoppingList», я получаю сообщение об ошибке, что оно не может найти модели. Эта же строка импорта работает из оболочки manage.py. Любые идеи?
Франк
33

runscriptиз джанго-расширений

python manage.py runscript scripty.py

Образец, script.pyчтобы проверить это:

from django.contrib.auth.models import User
print(User.objects.values())

Упоминается по адресу: http://django-extensions.readthedocs.io/en/latest/command_extensions.html и документируется по адресу:

python manage.py runscript --help

Также есть учебник .

Протестировано на Django 1.9.6, django-extensions 1.6.7.

Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
источник
1
Это лучший ответ, если вы уже используете django-extensions(вы должны). Примечание: похоже, runscriptиспользует стандартный django shell. Было бы замечательно, если бы он использовал shell_plus(также в расширениях), чтобы вам не пришлось импортировать все для простых скриптов.
grokpot
12

Если доступен IPython ( pip install ipython), он ./manage.py shellавтоматически использует его оболочку, а затем вы можете использовать магическую команду %run:

%run my_script.py
gitaarik
источник
Работал как шарм!
Roel
Это имеет преимущество перед тем, runscriptчто он работает со сценариями вне проекта / пакета и не жалуется, как этоTypeError: the 'package' argument is required to perform a relative import for
smido
8

Вы можете просто запустить скрипт с установленной DJANGO_SETTINGS_MODULEпеременной окружения. Это все, что нужно для настройки окружения Django-shell.

Это работает в Django> = 1.4

Властимил Зима
источник
7

@AtulVarma предоставил очень полезный комментарий под нерабочим принятым ответом :

echo 'import myscript' | python manage.py shell
raratiru
источник
отличный ответ! Я пропустил это в комментариях. Спасибо за размещение здесь
Anupam
6

если в вашем скрипте не так много команд, используйте его:

manage.py shell --command="import django; print(django.__version__)"

Джанго документы

MrNinjamannn
источник
4

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

Это сильно отличается от версии Django к версии Django. Если вы не нашли своего решения в этой теме, ответьте здесь - скрипт Django для доступа к объектам модели без использования оболочки manage.py - или подобные поиски могут вам помочь.

Я должен был начать my_command.py с

import os,sys
sys.path.append('/path/to/myproject')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.file")
import django
django.setup()

import project.app.models
#do things with my models, yay

а потом побежал python3 my_command.py

(Джанго 2.0.2)

Симона
источник
Это все еще работает для Django 3.0. Я заменил sys.path.append('/path/to/myproject')на BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))и `sys.path.append (BASE_DIR)`. Также не забудьте активировать виртуальную среду перед выполнением команды!
MRJ
3
import os, sys, django
os.environ["DJANGO_SETTINGS_MODULE"] = "settings"
sys.path.insert(0, os.getcwd())

django.setup()
user5121699
источник
1
Не могли бы вы отредактировать объяснение, почему этот код отвечает на вопрос таким образом, который отличается от некоторых из очень похожих предыдущих ответов? Ответы только на код не приветствуются , потому что они не учат решению.
Натан Тагги
2

Обратите внимание, этот метод не рекомендуется использовать для более поздних версий django! (> 1,3)

Альтернативный ответ, вы можете добавить это в начало my_script.py

from django.core.management import setup_environ
import settings
setup_environ(settings)

и выполнить my_script.pyтолько с Python в каталоге, где у вас есть, settings.pyно это немного глупо.

$ python my_script.py
danodonovan
источник
1

Если вы хотите, чтобы работать в BG еще лучше:

nohup echo 'exec(open("my_script.py").read())' | python manage.py shell &

Выход будет в nohup.out

Кевин Хе
источник
0

Что-то, что мне показалось интересным, это Django Scripts, который позволяет вам писать скрипты для запуска с помощью python manage.py runcript foobar. Более подробную информацию о реализации и структуре можно найти здесь, http://django-extensions.readthedocs.org/en/latest/index.html.

tseboho
источник
0

Попробуйте это, если вы используете виртуальную среду: -

оболочка python manage.py

для использования этих команд вы должны быть в виртуальной среде. для этого используйте: -

workon vir_env_name

например :-

dc@dc-comp-4:~/mysite$ workon jango
(jango)dc@dc-comp-4:~/mysite$ python manage.py shell
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

Примечание : - Здесь mysite - это имя моего сайта, а jango - имя моей виртуальной среды.

Рахул Сатал
источник
0

пришел сюда с тем же вопросом, что и ОП, и я нашел свой любимый ответ именно в ошибке в вопросе, которая работает также в Python 3:

./manage.py shell <<EOF
import my_script
my_script.main()
EOF
mariotomo
источник
0

Другой способ выполнить это:

echo 'execfile("/path_to/myscript.py")' | python manage.py shell --settings=config.base

Это работает на Python2.7 и Django1.9

Руслан Руденко
источник
0

Если вы хотите запустить скрипт запуска (например, импортировать некоторые модели django для интерактивной работы с ними) и остаться в оболочке django:

PYTHONSTARTUP=my_script.py python manage.py shell
Apogentus
источник
0

Оболочка django - это хороший способ выполнения модуля python со средой django, но не всегда легко и утомительно импортировать модули и выполнять функции вручную, особенно без автозаполнения. Чтобы решить эту проблему, я создал небольшой сценарий оболочки "runcript.sh", который позволяет в полной мере воспользоваться преимуществами автозаполнения и истории журналов консоли Linux.

NB. Скопируйте файл runcript.sh в корневой проект и установите право на выполнение (chmod + x).

Например: я хочу запустить функцию python с именем show (a, b, c) в модуле do_somethings.py в myapp / do_folder /

Стандартный способ django (manage.py shell):

python3 manage.py shell
 > from myapp.do_folder import do_somethings
 > do_somethings.show("p1", "p2"  , 3.14159)

С помощью скрипта (runcript.sh):

./runscript.sh myapp/do_folder/do_somethings.py show p1 p2 3.14159

Сценарий не ограничен в количестве аргументов. Однако поддерживаются только аргументы примитивных типов (int, float, string)

Martin13
источник
Привет, вероятно runscriptиз django-extensionsпакета сделать то же самое, проверьте это django-extensions.readthedocs.io/en/latest/runscript.html
frost-nzcr4
Спасибо frost-nzcr4. Да, действительно, это расширение работает, но я считаю, что оно ограничено папкой srcipts и только функцией run (). С моим srcipt вы можете выполнить функцию в любом месте любой папки.
Martin13
0

Поздно на вечеринку. Но это может быть полезно для кого-то.

Все, что вам нужно, это ваш скрипт и django-extensionsустановлен.

Просто запустите shell_plusдоступный django_extensionsи импортируйте скрипт, который вы написали.

Если ваш скрипт находится scpt.pyвнутри папки, folвы можете запустить скрипт следующим образом.

python manage.py shell_plus

и просто импортируйте ваш скрипт в оболочку следующим образом.

>>> from fol import scpt
Jarvis
источник
-1

Кажется, django.setup () не работает.

Похоже, не требуется.

это одно сработало.

import os, django, glob, sys, shelve
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myProject.settings")
davidj411
источник
1
django.setup (), безусловно, необходим для начальной загрузки среды Django.
colm.anseo