I am working with Django and use Django shell all the time. The annoying part is that while the Django server reloads on code changes, the shell does not, so every time I make a change to a method I am testing, I need to quit the shell and restart it, re-import all the modules I need, reinitialize all the variables I need etc. While iPython history saves a lot of typing on this, this is still a pain. Is there a way to make django shell auto-reload, the same way django development server does?
I know about reload(), but I import a lot of models and generally use
from app.models import * syntax, so reload() is not much help.
I recommend using the django-extensions project like stated above by dongweiming. But instead of just ‘shell_plus’ management command, use:
manage.py shell_plus --notebook
This will open a IPython notebook on your web browser. Write your code there in a cell, your imports etc. and run it.
When you change your modules, just click the notebook menu item ‘Kernel->Restart’
There you go, your code is now using your modified modules.
look at the manage.py shell_plus command provided by the django-extensions project. It will load all your model files on shell startup. and autoreload your any modify but do not need exit, you can direct call there
It seems that the general consensus on this topic, is that python reload() sucks and there is no good way to do this.
My solution to it is I write the code and save to a file and then use:
python manage.py shell < test.py
So I can make the change, save and run that command again till I fix whatever I’m trying to fix.
I’d suggest use IPython autoreload extension.
./manage.py shell In : %load_ext autoreload In : %autoreload 2
And from now all imported modules would be refreshed before evaluate.
In : from x import print_something In : print_something() Out: 'Something' # Do changes in print_something method in x.py file. In : print_something() Out: 'Something else'
Works also if something was imported before
%load_ext autoreload command.
./manage.py shell In : from x import print_something In : print_something() Out: 'Something' # Do changes in print_something method in x.py file. In : %load_ext autoreload In : %autoreload 2 In : print_something() Out: 'Something else'
There is possible also prevent some imports from refreshing with
%aimport command and 3 autoreload strategies:
- Reload all modules (except those excluded by %aimport) automatically
- Disable automatic reloading.
- Reload all modules imported with %aimport every time before executing
the Python code typed.
- Reload all modules (except those excluded by %aimport) every time
before executing the Python code typed.
- List modules which are to be automatically imported or not to be
- Import module ‘foo’ and mark it to be autoreloaded for %autoreload 1
- Mark module ‘foo’ to not be autoreloaded.
This generally works good for my use, but there are some cavetas:
- Replacing code objects does not always succeed: changing a @property in a class to an ordinary method or a method to a member variable can cause problems (but in old objects only).
- Functions that are removed (eg. via monkey-patching) from a module before it is reloaded are not upgraded.
- C extension modules cannot be reloaded, and so cannot be autoreloaded.
Reload() doesn’t work in Django shell without some tricks. You can check this thread na and my answer specifically:
My solution for this inconvenient follows. I am using IPython.
$ ./manage.py shell > import myapp.models as mdls # 'mdls' or whatever you want, but short... > mdls.SomeModel.objects.get(pk=100) > # At this point save some changes in the model > reload(mdls) > mdls.SomeModel.objects.get(pk=100)
Hope it helps. Of course it is for debug purposes.
Instead of running commands from the Django shell, you can set up a management command like so and rerun that each time.
Not exactly what you want, but I now tend to build myself management commands for testing and fiddling with things.
In the command you can set up a bunch of locals the way you want and afterwards drop into an interactive shell.
import code class Command(BaseCommand): def handle(self, *args, **kwargs): foo = 'bar' code.interact(local=locals())
No reload, but an easy and less annoying way to interactively test django functionality.