344

I need to execute a Python script from the Django shell. I tried:

./manage.py shell << my_script.py

But it didn't work. It was just waiting for me to write something.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • This is not how `django` works, what are you actually wanting to do? – danodonovan May 31 '13 at 09:08
  • 4
    `my_script.py` contains a few operations on one of my Django models. I already did this before but I can't remember how exactly. –  May 31 '13 at 09:10

27 Answers27

537

The << part is wrong, use < instead:

$ ./manage.py shell < myscript.py

You could also do:

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

For python3 you would need to use

>>> exec(open('myscript.py').read())
Jonathan
  • 8,453
  • 9
  • 51
  • 74
codeape
  • 97,830
  • 24
  • 159
  • 188
  • 18
    For me, this only executes the first line of the script. The only thing that works is combining both methods: `./manage.py shell < – Steve Bennett Jul 05 '13 at 00:49
  • It does not work anymore with Python 3+. Any idea to replace this? – David Dahan Apr 05 '15 at 13:27
  • 4
    @DavidD. The replacement is given in this answer [here](http://stackoverflow.com/questions/436198/what-is-an-alternative-to-execfile-in-python-3-0) – peter2108 Apr 23 '15 at 12:13
  • 1.9.6 passes the stdin to a `code.interact` https://github.com/django/django/blob/1.9.6/django/core/management/commands/shell.py#L101 | https://docs.python.org/2/library/code.html Likely the interactive nature of it breaks things. There should be a CLI option of `shell` to pass stdin to an `eval`. – Ciro Santilli OurBigBook.com May 13 '16 at 16:01
  • 17
    Another solution that appears to work for both Python 2.x and 3.x is `echo 'import myscript' | python manage.py shell`. I've found this can be useful for quick-and-dirty scripts that you only need to run once, without having to go through the cumbersome process of creating a `manage.py` command. – Atul Varma Jun 08 '16 at 15:02
  • the above comment even works with an installed ipython :) – acidjunk Sep 01 '16 at 13:41
  • And how can I use command line arguments to `myscript.py` in this manner? – Sean Letendre Dec 27 '18 at 02:48
  • 1
    if you're doing this on Windows power shell : `Get-Content myscript.py | .\manage.py shell` – Aditya Wirayudha Jun 02 '20 at 01:39
  • I've used ./manage.py shell < myscript.py with python 3. Worked flawlessly – Tech Jan 14 '21 at 07:15
  • I confirm that exec(open('myscript.py').read()) works currently in Django 3.1.5 shell – Serhii Kushchenko Feb 25 '21 at 09:06
292

You're not recommended to do that from the shell - and this is intended as you shouldn't really be executing random scripts from the django environment (but there are ways around this, see the other answers).

If this is a script that you will be running multiple times, it's a good idea to set it up as a custom command ie

 $ ./manage.py my_command

to do this create a file in a subdir of management and commands of your app, ie

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

and in this file define your custom command (ensuring that the name of the file is the name of the command you want to execute from ./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
pianoJames
  • 454
  • 1
  • 5
  • 14
danodonovan
  • 19,636
  • 10
  • 70
  • 78
  • 13
    Again this is the best answer. Since django 1.8 `NoArgsCommand` is deprecated. This page gives a working example : https://docs.djangoproject.com/en/1.9/howto/custom-management-commands/#module-django.core.management – Ger Mar 30 '16 at 20:16
  • 2
    As per earlier comment, for it to work for me I needed to change `def handle_noargs(self, **options):` to `def handle(self, **options):`. – James May 05 '17 at 09:15
  • Interesting link [here](http://thepythondjango.com/create-management-command-django/) in support to this answer and the documentation. – Mattia Paterna Nov 29 '17 at 10:34
  • 1
    To get it to work change to `def handle(self, **options):` as James's comment. – Omar Gonzales Dec 25 '18 at 13:11
  • For anyone having a problem with database values not being inserted correctly: this command option works far better than the first. I had an issue where string formatting wasn't working on a slug field. I wanted it to `string.lower()` and to replace some spaces with dashes. In a plain Python shell it worked perfectly, but not when adding to the database with the `exec(...)` function. Whereas this Django command worked perfectly. – CyberHavenProgramming Feb 03 '20 at 21:28
  • Here is the fresh link to the docs (the one in the answer doesn't work) https://docs.djangoproject.com/en/4.0/howto/custom-management-commands/ – Konstantin Kozirev May 30 '22 at 17:39
  • This is a great solution - you don't need the `__init__.py` files with Python 3.10/Django 4.1. – Ralph Bolton Apr 25 '23 at 07:32
127

For anyone using Django 1.7+, it seems that simply import the settings module is not enough.

After some digging, I found this Stack Overflow answer: https://stackoverflow.com/a/23241093

You now need to:

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

Without doing the above, I was getting a django.core.exceptions.AppRegistryNoReady error.

My script file is in the same directory as my django project (ie. in the same folder as manage.py)

Community
  • 1
  • 1
cgons
  • 1,301
  • 1
  • 8
  • 5
  • 2
    My setup has the settings file already referenced in the `DJANGO_SETTINGS_MODULE` environment variable. With that it was enough to just: `import django ; django.setup()` under 1.7. – Taylor D. Edmiston Jun 19 '15 at 19:50
  • 3
    With django 1.7+ this should be the accepted answer :) – acidjunk Jan 14 '16 at 13:39
  • 1
    This is definitively the correct answer for Django 1.9.x. Not running `django.setup()` will not let the script access Django models, not even import them! – glarrain Jun 26 '17 at 19:50
  • In a virtualenv you can simply `import django; django.setup()`. – User3759685 Jan 25 '18 at 13:35
  • 2
    You made my day! Thanks for this post. i was getting creazy on celery because i was not able to exec tasks onto management.call_command :D :D :D –  Jan 18 '19 at 23:20
  • 1
    This is very helpful to get started making a stand alone script that runs in Django environment. You may also want `import sys` and `sys.path.insert(0, ".")` and `sys.path.insert(0, "../lib")` or similar to be able to access libraries at different locations outside the start directory. The settings module name is just the directory names on the path to `settings.py` separated by `.` instead of `/`. – NeilG Mar 16 '20 at 11:42
  • Note that you need to put this at the top of the file, it won't work if you put it inside of `if __name__ == "__main__":` – Josh Correia Apr 16 '20 at 23:17
  • I faced this problem today, and later for a different problem I found your answer. <3 – let me down slowly Jun 01 '21 at 22:53
73

I'm late for the party but I hope that my response will help someone: You can do this in your Python script:

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

the rest of your stuff goes here ....

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
e-nouri
  • 2,576
  • 1
  • 21
  • 36
  • 3
    Also note that you can drop the `sys.path.append` stuff as long as you get `DJANGO_SETTINGS_MODULES` right (e.g. if you have a script sitting just above your site root you can do `os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'`). – mgalgs Mar 26 '14 at 05:49
  • I ended up doing `sys.path.append(os.getcwd())`, it works when I am inside my project directory, my DJANGO_SETTINGS_MODULE is correct and I try to run a script that import models, views, etc. – Danilo Cabello Jul 11 '14 at 16:04
  • yeah but you can't run it from anywhere ! – e-nouri Jul 11 '14 at 16:30
  • This doesn't work for me with django 1.6 - I have an app. I have set my path to include the django project directory and set up the project settings. But when I try and import my app with "from shoppinglist.models import ShoppingList" I am given an error that it can't find models. That same import line works from within the manage.py shell. Any ideas? – frankster Apr 08 '15 at 10:29
49

runscript from django-extensions

python manage.py runscript scripty.py

A sample script.py to test it out:

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

Mentioned at: http://django-extensions.readthedocs.io/en/latest/command_extensions.html and documented at:

python manage.py runscript --help

There is a tutorial too.

Tested on Django 1.9.6, django-extensions 1.6.7.

CoderGuy123
  • 6,219
  • 5
  • 59
  • 89
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • 1
    This is the best answer if you're already using `django-extensions` (you should). Note: It looks like `runscript` uses the standard django `shell`. It would be fantastic if it used `shell_plus` (also in extensions) so you didn't have to import everything for simple scripts. – grokpot Aug 30 '16 at 18:14
16

If IPython is available (pip install ipython) then ./manage.py shell will automatically use it's shell and then you can use the magic command %run:

%run my_script.py
gitaarik
  • 42,736
  • 12
  • 98
  • 105
  • This has the advantage over `runscript` that it works with scripts outside the project/package and does not complain like this `TypeError: the 'package' argument is required to perform a relative import for` – smido Apr 15 '20 at 09:49
15

@AtulVarma provided a very useful comment under the not-working accepted answer:

echo 'import myscript' | python manage.py shell
Community
  • 1
  • 1
raratiru
  • 8,748
  • 4
  • 73
  • 113
  • 1
    great answer! I missed it in the comments. Thanks for putting it here – Anupam May 08 '18 at 06:15
  • 1
    and the variation `cat ./my_script.py | python manage.py shell` – ddelange Dec 09 '22 at 17:00
  • 1
    This should be the correct answer, as a one-liner and just works! For anyone looking for this, the 'import script'can be inside a module, e.g. 'import mysite.script'. Works like a charm. – Daniel May 18 '23 at 14:47
14

If you don't have many commands in your script, use -c/--command:

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

Django stable docs on manage.py shell

Intrastellar Explorer
  • 3,005
  • 9
  • 52
  • 119
MrNinjamannn
  • 631
  • 7
  • 11
  • 1
    This mostly worked for me. Just wanted to add for if you do have a lot of commands in your script: `python manage.py shell --command="\`cat script_name.py\`"` – wile_e8 Jan 16 '23 at 20:58
10

I'm late for the party but I hope that my response will help someone: You can do this in your Python script:

step1: Import

import mysite.asgi

step2: Need to execute a Python script simply typing:

python test.py

Where test.py file like look this:

import mysite.asgi

from polls.models import GMD_TABLE
print ( [obj.gt_GMD_name for obj in GMD_TABLE.objects.all()] )

FINALY: The result will be:

['ISHWARDI', 'JHENAIDHA', 'HVDC CIRCLE']

Where ['ISHWARDI', 'JHENAIDHA', 'HVDC CIRCLE'] is the values of GMD_TABLE

8

You can just run the script with the DJANGO_SETTINGS_MODULE environment variable set. That's all it takes to set up Django-shell environment.

This works in Django >= 1.4

ziima
  • 706
  • 4
  • 17
6

As other answers indicate but don't explicitly state, what you may actually need is not necessarily to execute your script from the Django shell, but to access your apps without using the Django shell.

This differs a lot Django version to Django version. If you do not find your solution on this thread, answers here -- Django script to access model objects without using manage.py shell -- or similar searches may help you.

I had to begin my_command.py with

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

and then ran python3 my_command.py

(Django 2.0.2)

Simone
  • 156
  • 2
  • 7
  • 1
    This still works for Django 3.0. I replaced `sys.path.append('/path/to/myproject')` with `BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))` and ` sys.path.append(BASE_DIR)`. Also don't forget to activate your virtual env before executing the command! – mrj Jan 28 '20 at 12:16
4

You can simply run:

python manage.py shell < your_script.py

It should do the job!

Jéter Silveira
  • 329
  • 2
  • 6
3

Note, this method has been deprecated for more recent versions of django! (> 1.3)

An alternative answer, you could add this to the top of my_script.py

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

and execute my_script.py just with python in the directory where you have settings.py but this is a bit hacky.

$ python my_script.py
danodonovan
  • 19,636
  • 10
  • 70
  • 78
3
import os, sys, django
os.environ["DJANGO_SETTINGS_MODULE"] = "settings"
sys.path.insert(0, os.getcwd())

django.setup()
HaveNoDisplayName
  • 8,291
  • 106
  • 37
  • 47
  • 1
    Could you please [edit] in an explanation of why this code answers the question in a way that's different from some of the very similar earlier answers? Code-only answers are [discouraged](http://meta.stackexchange.com/q/148272/274165), because they don't teach the solution. – Nathan Tuggy Jul 16 '15 at 02:28
3

If you want to run in in BG even better:

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

The output will be in nohup.out

Kevin He
  • 1,210
  • 8
  • 19
1

If you want to execute startup script (e.g. import some django models to work with them interactively) and remain in django shell:

PYTHONSTARTUP=my_script.py python manage.py shell
Apogentus
  • 6,371
  • 6
  • 32
  • 33
1

Actually it is very simple, once you open django shell with python manage.py shell
then simply write
import test
to import test.py

# test.py
def x():
  print('hello');

Now you can execute the commands in this file as

test.x() //  will print hello
Akshay Vijay Jain
  • 13,461
  • 8
  • 60
  • 73
1

Add these lines to your python script.py

import os
import sys
import django
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent
sys.path.append(str(BASE_DIR))
    
os.environ.setdefault("DJANGO_SETTINGS_MODULE","django_server_app.settings")
django.setup()

# add your code here

then go to the project directory and run python script.py

SaimumIslam27
  • 971
  • 1
  • 8
  • 14
0

Something I just found to be interesting is Django Scripts, which allows you to write scripts to be run with python manage.py runscript foobar. More detailed information on implementation and scructure can be found here, http://django-extensions.readthedocs.org/en/latest/index.html

tseboho
  • 77
  • 10
0

django.setup() does not seem to work.

does not seem to be required either.

this alone worked.

import os, django, glob, sys, shelve
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myProject.settings")
davidj411
  • 985
  • 10
  • 10
0

Try this if you are using virtual enviroment :-

python manage.py shell

for using those command you must be inside virtual enviroment. for this use :-

workon vir_env_name

for example :-

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

Note :- Here mysite is my website name and jango is my virtual enviroment name

Rahul Satal
  • 2,107
  • 3
  • 32
  • 53
0

came here with the same question as the OP, and I found my favourite answer precisely in the mistake within the question, which works also in Python 3:

./manage.py shell <<EOF
import my_script
my_script.main()
EOF
mariotomo
  • 9,438
  • 8
  • 47
  • 66
0

Other way it's execute this one:

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

This is working on Python2.7 and Django1.9

0

The django shell is the good way to execute a python module with the django environment, but it is not always easy and tiresome to import modules and execute functions manually especially without auto-completion. To resolve this, I created a small shell script "runscript.sh" that allows you to take full advantage of the auto-completion and the log history of the Linux console.

NB: Copy runscript.sh to the root project and set the execute right (chmod +x)

For example: I want to run python function named show(a, b, c) in module do_somethings.py in myapp/do_folder/

The standard django way (manage.py shell):

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

With script (runscript.sh):

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

The script is not limited in number of arguments. However only arguments of primitive types are supported (int, float, string)

Martin13
  • 109
  • 9
  • 1
    Hi, probably `runscript` from `django-extensions` package do the same, check it https://django-extensions.readthedocs.io/en/latest/runscript.html – frost-nzcr4 Apr 16 '20 at 14:39
  • Thank you frost-nzcr4. Yes, indeed, this extension works, but I find it limited to the srcipts folder and only to the run() function. With my srcipt, you can execute a function anywhere in any folder. – Martin13 Apr 16 '20 at 16:08
  • @frost-nzcr4 , your url helped a lot, thnx ! – Vadim Mar 19 '21 at 16:09
0

Late to the party. But this might be helpful for someone.

All you need is your script and django-extensions installed.

Just run the shell_plus available in django_extensions and import the script that you've written.

If your script is scpt.py and it's inside a folder fol you can run the script as follows.

python manage.py shell_plus

and just import your script inside the shell as follows.

>>> from fol import scpt
Underoos
  • 4,708
  • 8
  • 42
  • 85
0

First check your file.

py manage.py

If your file is shown

[contracts]
category_load

Now you can run your .py file by typing in the powershell(terminal)

py manage.py category_load
Koops
  • 422
  • 3
  • 11
0

put globals().update(locals()) after importing statement

focus zheng
  • 345
  • 1
  • 4
  • 12