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ę.


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

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

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)


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


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.


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

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


7

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

echo 'import myscript' | python manage.py shell

świetna odpowiedź! Brakowało mi tego w komentarzach. Dzięki za umieszczenie go tutaj
Anupam


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)


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

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

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



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


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

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


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

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)


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

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

1
django.setup () jest z pewnością potrzebny do rozruchu środowiska Django.
colm.anseo 21.04.16
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.