Comment exécuter un script Python depuis le shell Django?

247

J'ai besoin d'exécuter un script Python à partir du shell Django. J'ai essayé:

./manage.py shell << my_script.py

Mais ça n'a pas marché. Il n'attendait que moi pour écrire quelque chose.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
Ce n'est pas ainsi que ça djangofonctionne, que voulez-vous réellement faire?
danodonovan
2
my_script.pycontient quelques opérations sur l'un de mes modèles Django. Je l'ai déjà fait auparavant, mais je ne me souviens pas exactement comment.

Réponses:

388

La <<pièce est fausse, utilisez <plutôt:

$ ./manage.py shell < myscript.py

Vous pourriez également faire:

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

Pour python3, vous devez utiliser

>>> exec(open('myscript.py').read())
codeape
la source
17
Pour moi, cela n'exécute que la première ligne du script. La seule chose qui fonctionne est de combiner les deux méthodes:./manage.py shell <<EOF\ execfile('myscript.py') \EOF
Steve Bennett
Cela ne fonctionne plus avec Python 3+. Une idée pour remplacer ça?
David D.
4
@DavidD. Le remplacement est donné dans cette réponse ici
peter2108
11
Une autre solution qui semble fonctionner pour Python 2.x et 3.x est echo 'import myscript' | python manage.py shell. J'ai trouvé que cela peut être utile pour les scripts rapides et sales que vous n'avez besoin d'exécuter qu'une seule fois, sans avoir à passer par le processus fastidieux de création d'une manage.pycommande.
Atul Varma
1
si vous faites cela sur Windows Power Shell: Get-Content myscript.py | .\manage.py shell
Aditya Wirayudha
219

Il n'est pas recommandé de le faire à partir du shell- et cela est prévu car vous ne devriez pas vraiment exécuter des scripts aléatoires à partir de l'environnement django (mais il existe des moyens de contourner cela, voir les autres réponses).

S'il s'agit d'un script que vous exécuterez plusieurs fois, c'est une bonne idée de le configurer comme une commande personnalisée, c'est-à-dire

 $ ./manage.py my_command

pour ce faire, créez un fichier dans un sous-répertoire de managementet commandsde votre app, c'est-à-dire

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

et dans ce fichier, définissez votre commande personnalisée (en vous assurant que le nom du fichier est le nom de la commande à partir de laquelle vous souhaitez exécuter ./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
la source
9
Encore une fois, c'est la meilleure réponse. Depuis Django 1.8 NoArgsCommandest obsolète. Cette page donne un exemple de travail: docs.djangoproject.com/en/1.9/howto/custom-management-commands/…
Ger
2
Selon un commentaire plus tôt, pour que cela fonctionne pour moi que je devais changer def handle_noargs(self, **options):pour def handle(self, **options):.
James
Lien intéressant ici à l'appui de cette réponse et de la documentation.
Mattia Paterna
1
Pour le faire fonctionner, changez def handle(self, **options):comme le commentaire de James.
Omar Gonzales
Réponse élégante. Merci beaucoup
Tessaracter
103

Pour tous ceux qui utilisent Django 1.7+, il semble que simplement importer le module des paramètres ne suffit pas.

Après quelques recherches, j'ai trouvé cette réponse Stack Overflow: https://stackoverflow.com/a/23241093

Vous devez maintenant:

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

Sans faire ce qui précède, j'obtenais une django.core.exceptions.AppRegistryNoReadyerreur.

Mon fichier de script se trouve dans le même répertoire que mon projet django (c'est-à-dire dans le même dossier que manage.py)

cgons
la source
2
Ma configuration a le fichier de paramètres déjà référencé dans la DJANGO_SETTINGS_MODULEvariable d'environnement. Avec cela, il suffisait de: import django ; django.setup()moins de 1,7.
Taylor Edmiston
1
Avec django 1.7+, cela devrait être la réponse acceptée :)
acidjunk
C'est définitivement la bonne réponse pour Django 1.9.x. Ne pas exécuter django.setup()ne permettra pas au script d'accéder aux modèles Django, pas même de les importer!
glarrain
Dans un virtualenv, vous pouvez simplement import django; django.setup().
User3759685
1
Tu as fait ma journée! Merci pour ce post. je devenais fou sur le céleri parce que je n'étais pas en mesure d'exécuter des tâches sur management.call_command: D: D: D
68

Je suis en retard pour la fête mais j'espère que ma réponse aidera quelqu'un: vous pouvez le faire dans votre script Python:

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

le reste de vos affaires va ici ....

e-nouri
la source
3
Notez également que vous pouvez supprimer le sys.path.appendcontenu aussi longtemps que vous le souhaitez DJANGO_SETTINGS_MODULES(par exemple, si vous avez un script juste au-dessus de la racine de votre site, vous pouvez le faire os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings').
mgalgs
J'ai fini par le faire sys.path.append(os.getcwd()), cela fonctionne lorsque je suis dans mon répertoire de projet, mon DJANGO_SETTINGS_MODULE est correct et j'essaie d'exécuter un script qui importe des modèles, des vues, etc.
Danilo Cabello
oui mais vous ne pouvez pas l'exécuter de n'importe où!
e-nouri
Cela ne fonctionne pas pour moi avec django 1.6 - j'ai une application. J'ai défini mon chemin d'accès pour inclure le répertoire du projet django et configurer les paramètres du projet. Mais lorsque j'essaie d'importer mon application avec "from shoppinglist.models import ShoppingList", je reçois une erreur indiquant qu'elle ne trouve pas de modèles. Cette même ligne d'importation fonctionne à partir du shell manage.py. Des idées?
frankster
33

runscriptde django-extensions

python manage.py runscript scripty.py

Un échantillon script.pypour le tester:

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

Mentionné sur: http://django-extensions.readthedocs.io/en/latest/command_extensions.html et documenté sur:

python manage.py runscript --help

Il y a aussi un tutoriel .

Testé sur Django 1.9.6, django-extensions 1.6.7.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
1
C'est la meilleure réponse si vous utilisez déjà django-extensions(vous devriez). Remarque: Il semble que runscriptle django standard soit utilisé shell. Ce serait fantastique s'il était utilisé shell_plus(également dans les extensions) afin que vous n'ayez pas à tout importer pour des scripts simples.
grokpot
12

Si IPython est disponible ( pip install ipython), il ./manage.py shellutilisera automatiquement son shell et vous pourrez alors utiliser la commande magique %run:

%run my_script.py
gitaarik
la source
A fonctionné comme un charme!
Roel
Cela a l'avantage sur le runscriptfait qu'il fonctionne avec des scripts en dehors du projet / package et ne se plaint pas comme çaTypeError: the 'package' argument is required to perform a relative import for
smido
8

Vous pouvez simplement exécuter le script avec l' DJANGO_SETTINGS_MODULEensemble de variables d'environnement. C'est tout ce qu'il faut pour configurer l'environnement Django-shell.

Cela fonctionne dans Django> = 1.4

Vlastimil Zíma
la source
7

@AtulVarma a fourni un commentaire très utile sous la réponse acceptée non fonctionnelle :

echo 'import myscript' | python manage.py shell
raratiru
la source
très bonne réponse! Je l'ai manqué dans les commentaires. Merci de l'avoir mis ici
Anupam
6

si vous n'avez pas beaucoup de commandes dans votre script, utilisez-le:

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

Documents Django

MrNinjamannn
la source
4

Comme d'autres réponses l'indiquent mais ne le disent pas explicitement, ce dont vous pourriez avoir besoin n'est pas nécessairement d'exécuter votre script à partir du shell Django, mais d'accéder à vos applications sans utiliser le shell Django .

Cela diffère beaucoup de la version Django de la version Django. Si vous ne trouvez pas votre solution sur ce fil, les réponses ici - Script Django pour accéder aux objets du modèle sans utiliser le shell manage.py - ou des recherches similaires peuvent vous aider.

Je devais commencer my_command.py par

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

puis a couru python3 my_command.py

(Django 2.0.2)

Simone
la source
Cela fonctionne toujours pour Django 3.0. J'ai remplacé sys.path.append('/path/to/myproject')par BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))et `sys.path.append (BASE_DIR)`. N'oubliez pas non plus d'activer votre env virtuel avant d'exécuter la commande!
mrj
3
import os, sys, django
os.environ["DJANGO_SETTINGS_MODULE"] = "settings"
sys.path.insert(0, os.getcwd())

django.setup()
user5121699
la source
1
Pourriez-vous s'il vous plaît modifier une explication de la raison pour laquelle ce code répond à la question d'une manière différente de certaines des réponses précédentes très similaires? Les réponses uniquement codées sont déconseillées , car elles n'enseignent pas la solution.
Nathan Tuggy
2

Notez que cette méthode est déconseillée pour les versions plus récentes de django! (> 1.3)

Une autre réponse, vous pouvez l'ajouter en haut de my_script.py

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

et exécutez my_script.pyjuste avec python dans le répertoire où vous avez, settings.pymais c'est un peu hacky.

$ python my_script.py
danodonovan
la source
1

Si vous voulez encore mieux utiliser BG:

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

La sortie sera en nohup.out

Kevin He
la source
0

Quelque chose que je viens de trouver intéressant est Django Scripts, qui vous permet d'écrire des scripts à exécuter avec python manage.py runscript foobar. Des informations plus détaillées sur la mise en œuvre et la structure sont disponibles ici, http://django-extensions.readthedocs.org/en/latest/index.html

tseboho
la source
0

Essayez ceci si vous utilisez un environnement virtuel: -

shell python manage.py

pour utiliser ces commandes, vous devez être dans un environnement virtuel. pour cette utilisation: -

workon vir_env_name

par exemple :-

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

Remarque : - Ici, mysite est le nom de mon site Web et jango est le nom de mon environnement virtuel

Rahul Satal
la source
0

est venu ici avec la même question que l'OP, et j'ai trouvé ma réponse préférée précisément dans l'erreur dans la question, qui fonctionne également en Python 3:

./manage.py shell <<EOF
import my_script
my_script.main()
EOF
mariotomo
la source
0

Sinon, exécutez celui-ci:

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

Cela fonctionne sur Python2.7 et Django1.9

Руслан Руденко
la source
0

Si vous souhaitez exécuter un script de démarrage (par exemple, importer certains modèles django pour travailler avec eux de manière interactive) et rester dans le shell django:

PYTHONSTARTUP=my_script.py python manage.py shell
Apogentus
la source
0

Le shell django est le bon moyen d'exécuter un module python avec l'environnement django, mais il n'est pas toujours facile et fastidieux d'importer des modules et d'exécuter des fonctions manuellement, surtout sans auto-complétion. Pour résoudre ce problème, j'ai créé un petit script shell "runscript.sh" qui vous permet de profiter pleinement de l'auto-complétion et de l'historique des journaux de la console Linux.

NB: Copiez runscript.sh dans le projet racine et définissez le droit d'exécution (chmod + x)

Par exemple: je veux exécuter la fonction python nommée show (a, b, c) dans le module do_somethings.py dans myapp / do_folder /

La manière standard de Django (shell manage.py):

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

Avec script (runscript.sh):

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

Le script n'est pas limité en nombre d'arguments. Cependant, seuls les arguments de types primitifs sont pris en charge (int, float, string)

Martin13
la source
Salut, probablement runscriptdu django-extensionspackage faire la même chose, vérifiez-le django-extensions.readthedocs.io/en/latest/runscript.html
frost-nzcr4
Merci frost-nzcr4. Oui, en effet, cette extension fonctionne, mais je la trouve limitée au dossier srcipts et uniquement à la fonction run (). Avec mon srcipt, vous pouvez exécuter une fonction n'importe où dans n'importe quel dossier.
Martin13
0

Tard à la fête. Mais cela pourrait être utile pour quelqu'un.

Tout ce dont vous avez besoin est votre script et django-extensionsinstallé.

Exécutez simplement le shell_plusdisponible dans django_extensionset importez le script que vous avez écrit.

Si votre script se trouve scpt.pyet se trouve dans un dossier, folvous pouvez exécuter le script comme suit.

python manage.py shell_plus

et importez simplement votre script à l'intérieur du shell comme suit.

>>> from fol import scpt
Jarvis
la source
-1

django.setup () ne semble pas fonctionner.

ne semble pas non plus nécessaire.

cela seul a fonctionné.

import os, django, glob, sys, shelve
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myProject.settings")
davidj411
la source
1
django.setup () est très certainement nécessaire pour amorcer l'environnement Django.
colm.anseo