Jak wykonać skrypt Pythona z powłoki Django?

247

Muszę wykonać skrypt Pythona z powłoki Django. Próbowałem:

./manage.py shell << my_script.py

Ale to nie zadziałało. Czekałem, aż coś napiszę.

Ciro Santilli
źródło
Nie tak to djangodziała, co tak naprawdę chcesz zrobić?
danodonovan
2
my_script.pyzawiera kilka operacji na jednym z moich modeli Django. Zrobiłem to już wcześniej, ale nie pamiętam, jak dokładnie.

Odpowiedzi:

388

<<Część jest źle, użyj <zamiast:

$ ./manage.py shell < myscript.py

Możesz także:

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

W przypadku python3 musisz użyć

>>> exec(open('myscript.py').read())
Codeape
źródło
17
Dla mnie wykonuje to tylko pierwszy wiersz skryptu. Jedyne, co działa, to połączenie obu metod:./manage.py shell <<EOF\ execfile('myscript.py') \EOF
Steve Bennett
To już nie działa z Python 3+. Masz pomysł, aby to zastąpić?
David D.
4
@DavidD.
Zastępstwo
11
Innym rozwiązaniem, które wydaje się działać zarówno w Pythonie 2.x, jak i 3.x jest echo 'import myscript' | python manage.py shell. Odkryłem, że może to być przydatne w przypadku szybkich i brudnych skryptów, które trzeba uruchomić tylko raz, bez konieczności przechodzenia przez uciążliwy proces tworzenia manage.pypolecenia.
Atul Varma
1
jeśli robisz to w systemie Windows Power Shell: Get-Content myscript.py | .\manage.py shell
Aditya Wirayudha
219

Nie zaleca się tego robić z shell- a jest to zamierzone, ponieważ tak naprawdę nie powinieneś wykonywać losowych skryptów ze środowiska django (ale są na to sposoby, zobacz inne odpowiedzi).

Jeśli jest to skrypt, który będziesz uruchamiał wiele razy, dobrym pomysłem jest skonfigurowanie go jako polecenia niestandardowego, tj

 $ ./manage.py my_command

w tym celu utwórz plik w podkatalogu managementi commandsswoim app, tj

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

iw tym pliku zdefiniuj niestandardowe polecenie (upewniając się, że nazwa pliku to nazwa polecenia, z którego chcesz wykonać ./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
źródło
9
To znowu najlepsza odpowiedź. Ponieważ django 1.8 NoArgsCommandjest przestarzałe. Ta strona zawiera działający przykład: docs.djangoproject.com/en/1.9/howto/custom-management-commands/…
Ger
2
Zgodnie z wcześniejszym komentarzem, aby działało dla mnie, musiałem się zmienić def handle_noargs(self, **options):na def handle(self, **options):.
James
Interesujący link tutaj na poparcie tej odpowiedzi i dokumentacji.
Mattia Paterna
1
Aby to zadziałało, zmień def handle(self, **options):na komentarz Jamesa.
Omar Gonzales,
Elegancka odpowiedź.
Wielkie
103

Dla każdego, kto używa Django 1.7+, wydaje się, że po prostu import modułu ustawień nie wystarczy.

Po pewnym kopaniu znalazłem odpowiedź Przepełnienie stosu: https://stackoverflow.com/a/23241093

Teraz musisz:

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

Bez powyższego dostałem django.core.exceptions.AppRegistryNoReadybłąd.

Mój plik skryptu znajduje się w tym samym katalogu, co mój projekt django (tj. W tym samym folderze co manage.py)

Cgons
źródło
2
Moja konfiguracja ma już plik ustawień, do którego odwołuje się DJANGO_SETTINGS_MODULEzmienna środowiskowa. Wystarczyło to: import django ; django.setup()poniżej 1,7.
Taylor Edmiston,
1
W przypadku django 1.7+ powinna to być zaakceptowana odpowiedź :)
acidjunk
Jest to zdecydowanie poprawna odpowiedź dla Django 1.9.x. Brak działania django.setup()nie pozwoli skryptowi uzyskać dostępu do modeli Django, nawet ich nie zaimportować!
glarrain
W virtualenv możesz po prostu import django; django.setup().
User3759685
1
Sprawiłeś, że mój dzień! Dzięki za ten post. robiłem się zwariowany na seler, ponieważ nie byłem w stanie wykonać zadań na management.call_command: D: D: D
68

Spóźniam się na przyjęcie, ale mam nadzieję, że moja odpowiedź komuś pomoże: Możesz to zrobić w skrypcie Python:

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

reszta twoich rzeczy trafia tutaj ....

e-nouri
źródło
3
Zauważ też, że możesz upuścić sys.path.appendrzeczy, dopóki masz DJANGO_SETTINGS_MODULESrację (np. Jeśli skrypt znajduje się tuż nad katalogiem głównym witryny, możesz to zrobić os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings').
mgalgs
Skończyło się na tym sys.path.append(os.getcwd()), że działa, kiedy jestem w katalogu projektu, mój DJANGO_SETTINGS_MODULE jest poprawny i próbuję uruchomić skrypt, który importuje modele, widoki itp.
Danilo Cabello
tak, ale nie można go uruchomić z dowolnego miejsca!
e-nouri
To nie działa dla mnie z django 1.6 - Mam aplikację. Ustawiłem ścieżkę, aby zawierała katalog projektu django i skonfigurowałem ustawienia projektu. Ale kiedy próbuję zaimportować aplikację za pomocą polecenia „z shoppinglist.models import ShoppingList”, pojawia się błąd, że nie można znaleźć modeli. Ta sama linia importu działa z poziomu powłoki manage.py. Jakieś pomysły?
frankster
33

runscriptz rozszerzeń django

python manage.py runscript scripty.py

Próbka script.pydo przetestowania:

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

Wspomniany na: http://django-extensions.readthedocs.io/en/latest/command_extensions.html i udokumentowany na:

python manage.py runscript --help

Jest też samouczek .

Testowane na Django 1.9.6, rozszerzenia django 1.6.7.

Ciro Santilli
źródło
1
To najlepsza odpowiedź, jeśli już korzystasz django-extensions(powinieneś). Uwaga: wygląda na to, że runscriptużywa standardowego django shell. Byłoby fantastycznie, gdyby był używany shell_plus(także w rozszerzeniach), więc nie trzeba było importować wszystkiego dla prostych skryptów.
grokpot
12

Jeśli IPython jest dostępny ( pip install ipython) ./manage.py shell, automatycznie użyje jego powłoki, a następnie możesz użyć magicznego polecenia %run:

%run my_script.py
gitaarik
źródło
Działa jak urok!
Roel
Ma to tę zaletę runscript, że działa ze skryptami spoza projektu / pakietu i nie narzeka w ten sposóbTypeError: the 'package' argument is required to perform a relative import for
smido
8

Możesz po prostu uruchomić skrypt z DJANGO_SETTINGS_MODULEustawioną zmienną środowiskową. To wszystko, czego potrzeba, aby skonfigurować środowisko powłoki Django.

Działa to w Django> = 1.4

Vlastimil Zíma
źródło
7

@AtulVarma podał bardzo przydatny komentarz pod niedziałającą zaakceptowaną odpowiedzią :

echo 'import myscript' | python manage.py shell
raratiru
źródło
świetna odpowiedź! Brakowało mi tego w komentarzach. Dzięki za umieszczenie go tutaj
Anupam
6

jeśli nie masz wielu poleceń w skrypcie, użyj go:

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

Dokumenty Django

MrNinjamannn
źródło
4

Jak inne odpowiedzi wskazują, ale nie jednoznacznie stwierdzają, może to nie być konieczne do wykonania skryptu z powłoki Django, ale do uzyskania dostępu do aplikacji bez użycia powłoki Django .

Różni się bardzo wersja Django od wersji Django. Jeśli nie znajdziesz rozwiązania dla tego wątku, odpowiedz tutaj - skrypt Django, aby uzyskać dostęp do obiektów modelu bez użycia powłoki manage.py - lub podobne wyszukiwania mogą ci pomóc.

Musiałem zacząć od 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

a następnie pobiegł python3 my_command.py

(Django 2.0.2)

Simone
źródło
To nadal działa dla Django 3.0. Wymieniłem sys.path.append('/path/to/myproject')z BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))i `sys.path.append (BASE_DIR)`. Nie zapomnij również aktywować wirtualnej env przed wykonaniem polecenia!
mrj
3
import os, sys, django
os.environ["DJANGO_SETTINGS_MODULE"] = "settings"
sys.path.insert(0, os.getcwd())

django.setup()
użytkownik5121699
źródło
1
Czy mógłbyś edytować wyjaśnienie, dlaczego ten kod odpowiada na pytanie w sposób odmienny od niektórych bardzo podobnych wcześniejszych odpowiedzi? Odpowiedzi zawierające tylko kod są odradzane , ponieważ nie uczą rozwiązania.
Nathan Tuggy,
2

Uwaga, ta metoda została uznana za przestarzałą w przypadku nowszych wersji django! (> 1.3)

Alternatywną odpowiedź można dodać na początku my_script.py

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

i wykonaj my_script.pytylko z pythonem w katalogu, w którym masz, settings.pyale jest to trochę hacky.

$ python my_script.py
danodonovan
źródło
1

Jeśli chcesz wpaść w BG jeszcze lepiej:

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

Wyjście będzie w nohup.out

Kevin He
źródło
0

Coś, co właśnie uznałem za interesujące, to Django Scripts, które pozwalają pisać skrypty uruchamiane za pomocą foobara skryptów uruchomieniowych python manage.py. Bardziej szczegółowe informacje na temat implementacji i struktury można znaleźć tutaj, http://django-extensions.readthedocs.org/en/latest/index.html

tseboho
źródło
0

Wypróbuj to, jeśli korzystasz z wirtualnego środowiska: -

powłoka python manage.py

do korzystania z tych poleceń musisz znajdować się w środowisku wirtualnym. do tego zastosowania:

workon nazwa_env_wir

na przykład :-

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)
>>> 

Uwaga : - tutaj moja nazwa witryny to moja strona internetowa, a jango to nazwa mojego wirtualnego środowiska

Rahul Satal
źródło
0

przyszedł tutaj z tym samym pytaniem co OP, a moją ulubioną odpowiedź znalazłem właśnie w błędzie w pytaniu, które działa również w Pythonie 3:

./manage.py shell <<EOF
import my_script
my_script.main()
EOF
mariotomo
źródło
0

Innym sposobem jest wykonanie tego:

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

Działa to na Python2.7 i Django1.9

Руслан Руденко
źródło
0

Jeśli chcesz uruchomić skrypt startowy (np. Zaimportować niektóre modele django, aby pracować z nimi interaktywnie) i pozostać w powłoce django:

PYTHONSTARTUP=my_script.py python manage.py shell
Apogentus
źródło
0

Powłoka django jest dobrym sposobem na uruchomienie modułu python ze środowiskiem django, ale importowanie modułów i wykonywanie funkcji ręcznie nie zawsze jest łatwe i męczące, zwłaszcza bez automatycznego uzupełniania. Aby rozwiązać ten problem, stworzyłem mały skrypt powłoki „Runcript.sh” który pozwala w pełni skorzystać z automatycznego uzupełniania i historii logowania konsoli Linux.

NB: Skopiuj plik Runcript.sh do projektu głównego i ustaw prawidłowe wykonanie (chmod + x)

Na przykład: chcę uruchomić funkcję Pythona o nazwie show (a, b, c) w module do_somethings.py w myapp / do_folder /

Standardowy sposób django (powłoka manage.py):

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

Ze skryptem (Runcript.sh):

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

Skrypt nie jest ograniczony liczbą argumentów. Obsługiwane są jednak tylko argumenty typów pierwotnych (int, float, string)

Martin13
źródło
Cześć, prawdopodobnie runscriptz django-extensionspakietu zrobić to samo, sprawdź to django-extensions.readthedocs.io/en/latest/runscript.html
frost-nzcr4
Dziękuję frost-nzcr4. Tak, rzeczywiście, to rozszerzenie działa, ale uważam, że jest ograniczone do folderu srcipts i tylko do funkcji run (). Z moim srciptem możesz wykonać funkcję w dowolnym miejscu w dowolnym folderze.
Martin13
0

Późno na imprezę. Ale może to być pomocne dla kogoś.

Wszystko czego potrzebujesz to skrypt i django-extensionszainstalowany.

Wystarczy uruchomić shell_plusdostępny django_extensionsi zaimportować napisany skrypt.

Jeśli twój skrypt znajduje scpt.pysię w folderze, folmożesz go uruchomić w następujący sposób.

python manage.py shell_plus

i po prostu zaimportuj skrypt do powłoki w następujący sposób.

>>> from fol import scpt
Jarvis
źródło
-1

django.setup () nie działa.

nie wydaje się również wymagane.

to samo działało.

import os, django, glob, sys, shelve
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myProject.settings")
davidj411
źródło
1
django.setup () jest z pewnością potrzebny do rozruchu środowiska Django.
colm.anseo 21.04.16