¿Cómo ejecutar un script Python desde el shell Django?

247

Necesito ejecutar un script Python desde el shell Django. Lo intenté:

./manage.py shell << my_script.py

Pero no funcionó. Solo estaba esperando que yo escribiera algo.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
Así no es como djangofunciona, ¿qué es lo que realmente quieres hacer?
danodonovan
2
my_script.pycontiene algunas operaciones en uno de mis modelos de Django. Ya hice esto antes pero no recuerdo exactamente cómo.

Respuestas:

388

La <<parte está mal, use <en su lugar:

$ ./manage.py shell < myscript.py

También puedes hacer:

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

Para python3 necesitarías usar

>>> exec(open('myscript.py').read())
codeape
fuente
17
Para mí, esto solo ejecuta la primera línea del script. Lo único que funciona es combinar ambos métodos:./manage.py shell <<EOF\ execfile('myscript.py') \EOF
Steve Bennett
Ya no funciona con Python 3+. ¿Alguna idea para reemplazar esto?
David D.
44
@DavidD. El reemplazo se da en esta respuesta aquí
peter2108
11
Otra solución que parece funcionar tanto para Python 2.xy 3.x es echo 'import myscript' | python manage.py shell. He descubierto que esto puede ser útil para scripts rápidos y sucios que solo necesita ejecutar una vez, sin tener que pasar por el engorroso proceso de crear un manage.pycomando.
Atul Varma
1
si está haciendo esto en Windows Power Shell: Get-Content myscript.py | .\manage.py shell
Aditya Wirayudha
219

Usted no está recomendada de hacer que desde el shell- y ello se pretende, ya que no realmente debería estar ejecutando scripts de azar desde el entorno Django (pero no son formas de evitar esto, ver las otras respuestas).

Si se trata de un script que ejecutará varias veces, es una buena idea configurarlo como un comando personalizado, es decir

 $ ./manage.py my_command

para hacer esto crea un archivo en un subdirectorio de managementy commandsde tu app, es decir

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

y en este archivo defina su comando personalizado (asegurándose de que el nombre del archivo sea el nombre del comando desde el que desea ejecutar ./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
fuente
99
Nuevamente, esta es la mejor respuesta. Dado que django 1.8 NoArgsCommandestá en desuso. Esta página ofrece un ejemplo de trabajo: docs.djangoproject.com/en/1.9/howto/custom-management-commands/…
Ger
2
Según comentario anterior, para que funcione para mí que necesitaba cambiar def handle_noargs(self, **options):a def handle(self, **options):.
James
Enlace interesante aquí en apoyo de esta respuesta y la documentación.
Mattia Paterna
1
Para que funcione, cambia def handle(self, **options):como el comentario de James.
Omar Gonzales
Respuesta elegante Muchas gracias
Tessaracter
103

Para cualquiera que use Django 1.7+, parece que simplemente importar el módulo de configuración no es suficiente.

Después de investigar un poco, encontré esta respuesta de desbordamiento de pila: https://stackoverflow.com/a/23241093

Ahora necesita:

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

Sin hacer lo anterior, recibí un django.core.exceptions.AppRegistryNoReadyerror.

Mi archivo de script está en el mismo directorio que mi proyecto django (es decir, en la misma carpeta que manage.py)

cgons
fuente
2
Mi configuración tiene el archivo de configuración ya referenciado en la DJANGO_SETTINGS_MODULEvariable de entorno. Con eso fue suficiente para solo: import django ; django.setup()menos de 1.7.
Taylor Edmiston
1
Con django 1.7+ esta debería ser la respuesta aceptada :)
acidjunk
Esta es definitivamente la respuesta correcta para Django 1.9.x. No ejecutar django.setup()no permitirá que el script acceda a los modelos de Django, ¡ni siquiera los importará!
glarrain
En un virtualenv puedes simplemente import django; django.setup().
Usuario3759685
1
¡Me has alegrado el día! Gracias por este post me estaba poniendo crujiente por el apio porque no podía ejecutar tareas en management.call_command: D: D: D
68

Llego tarde a la fiesta, pero espero que mi respuesta ayude a alguien: puede hacer esto en su script de Python:

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

el resto de tus cosas va aquí ...

e-nouri
fuente
3
También tenga en cuenta que puede soltar las sys.path.appendcosas siempre que lo haga DJANGO_SETTINGS_MODULEScorrectamente (por ejemplo, si tiene un script sentado justo encima de la raíz de su sitio, puede hacerlo os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings').
mgalgs
Terminé haciendo sys.path.append(os.getcwd()), funciona cuando estoy dentro del directorio de mi proyecto, mi DJANGO_SETTINGS_MODULE es correcto e intento ejecutar un script que importe modelos, vistas, etc.
Danilo Cabello
Sí, pero no puedes ejecutarlo desde cualquier lugar.
e-nouri
Esto no funciona para mí con django 1.6: tengo una aplicación. He configurado mi ruta para incluir el directorio del proyecto django y configurar los ajustes del proyecto. Pero cuando intento importar mi aplicación con "from shoppinglist.models import ShoppingList" aparece un error que dice que no puede encontrar modelos. Esa misma línea de importación funciona desde el shell manage.py. ¿Algunas ideas?
frankster
33

runscriptde django-extensiones

python manage.py runscript scripty.py

Una muestra script.pypara probarlo:

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

Mencionado en: http://django-extensions.readthedocs.io/en/latest/command_extensions.html y documentado en:

python manage.py runscript --help

También hay un tutorial .

Probado en Django 1.9.6, django-extensions 1.6.7.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
1
Esta es la mejor respuesta si ya está usando django-extensions(debería). Nota: Parece que runscriptusa el django estándar shell. Sería fantástico si se usara shell_plus(también en extensiones) para que no tuviera que importar todo para scripts simples.
grokpot
12

Si IPython está disponible ( pip install ipython), ./manage.py shellusará automáticamente su shell y luego podrá usar el comando mágico %run:

%run my_script.py
gitaarik
fuente
¡Trabajado como un encanto!
Roel
Esto tiene la ventaja de runscriptque funciona con scripts fuera del proyecto / paquete y no se queja asíTypeError: the 'package' argument is required to perform a relative import for
smido
8

Simplemente puede ejecutar el script con el DJANGO_SETTINGS_MODULEconjunto de variables de entorno. Eso es todo lo que se necesita para configurar el entorno Django-shell.

Esto funciona en Django> = 1.4

Vlastimil Zíma
fuente
7

@AtulVarma proporcionó un comentario muy útil bajo la respuesta aceptada que no funciona :

echo 'import myscript' | python manage.py shell
raratiru
fuente
¡gran respuesta! Lo extrañé en los comentarios. Gracias por ponerlo aquí
Anupam
6

si no tiene muchos comandos en su script, úselo:

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

Django docs

MrNinjamannn
fuente
4

Como otras respuestas indican pero no indican explícitamente, lo que realmente puede necesitar no es necesariamente ejecutar su script desde el shell Django, sino acceder a sus aplicaciones sin usar el shell Django .

Esto difiere mucho de la versión de Django a la versión de Django. Si no encuentra su solución en este hilo, responda aquí ( script de Django para acceder a los objetos del modelo sin utilizar el shell manage.py ) o búsquedas similares pueden ayudarlo.

Tenía que comenzar my_command.py con

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

y luego corrió python3 my_command.py

(Django 2.0.2)

Simone
fuente
Esto todavía funciona para Django 3.0. He sustituido sys.path.append('/path/to/myproject')con BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))y `sys.path.append (BASE_DIR)`. ¡Además, no olvide activar su entorno virtual antes de ejecutar el comando!
mrj
3
import os, sys, django
os.environ["DJANGO_SETTINGS_MODULE"] = "settings"
sys.path.insert(0, os.getcwd())

django.setup()
usuario5121699
fuente
1
¿Podría por favor editar una explicación de por qué este código responde a la pregunta de una manera diferente de algunas de las respuestas anteriores muy similares? Se desaconsejan las respuestas de solo código , porque no enseñan la solución.
Nathan Tuggy
2

¡Tenga en cuenta que este método ha quedado en desuso para versiones más recientes de django! (> 1.3)

Una respuesta alternativa, podría agregar esto al principio de my_script.py

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

y ejecuta my_script.pysolo con python en el directorio donde tienes settings.pypero esto es un poco hacky.

$ python my_script.py
danodonovan
fuente
1

Si quieres correr en BG aún mejor:

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

La salida estará en nohup.out

Kevin He
fuente
0

Pruebe esto si está utilizando un entorno virtual: -

Python manage.py shell

para usar esos comandos debes estar dentro del entorno virtual. para este uso: -

workon vir_env_name

por ejemplo :-

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

Nota : - aquí mysite es el nombre de mi sitio web y jango es mi nombre de entorno virtual

Rahul Satal
fuente
0

Vine aquí con la misma pregunta que el OP, y encontré mi respuesta favorita precisamente en el error dentro de la pregunta, que también funciona en Python 3:

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

Otra forma es ejecutar este:

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

Esto está funcionando en Python2.7 y Django1.9

Руслан Руденко
fuente
0

Si desea ejecutar un script de inicio (por ejemplo, importe algunos modelos de django para trabajar con ellos de forma interactiva) y permanezca en el shell de django:

PYTHONSTARTUP=my_script.py python manage.py shell
Apogentus
fuente
0

El shell django es la buena manera de ejecutar un módulo de Python con el entorno django, pero no siempre es fácil y cansado importar módulos y ejecutar funciones manualmente, especialmente sin autocompletar. Para resolver esto, creé un pequeño script de shell "runscript.sh" que le permite aprovechar al máximo la finalización automática y el historial de registro de la consola de Linux.

NB: Copie runscript.sh al proyecto raíz y configure la ejecución correcta (chmod + x)

Por ejemplo: quiero ejecutar la función de Python llamada show (a, b, c) en el módulo do_somethings.py en myapp / do_folder /

La forma estándar de django (manage.py shell):

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

Con script (runcript.sh):

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

El guión no está limitado en número de argumentos. Sin embargo, solo se admiten argumentos de tipos primitivos (int, float, string)

Martin13
fuente
Hola, probablemente runscriptdesde el django-extensionspaquete haga lo mismo, compruébelo django-extensions.readthedocs.io/en/latest/runscript.html
frost-nzcr4
Gracias frost-nzcr4. Sí, de hecho, esta extensión funciona, pero la encuentro limitada a la carpeta srcipts y solo a la función run (). Con mi srcipt, puede ejecutar una función en cualquier lugar de cualquier carpeta.
Martin13
0

Tarde a la fiesta. Pero esto podría ser útil para alguien.

Todo lo que necesitas es tu script e django-extensionsinstalado.

Simplemente ejecute el shell_plusdisponible django_extensionse importe el script que ha escrito.

Si su script está scpt.pyy está dentro de una carpeta fol, puede ejecutar el script de la siguiente manera.

python manage.py shell_plus

e importa tu script dentro del shell de la siguiente manera.

>>> from fol import scpt
Jarvis
fuente
-1

django.setup () no parece funcionar.

tampoco parece ser necesario.

esto solo funcionó.

import os, django, glob, sys, shelve
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myProject.settings")
davidj411
fuente
1
django.setup () es ciertamente necesario para arrancar el entorno Django.
colm.anseo