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 ma
It seems that the general consensus on this topic, is that python reload() sucks and there is no good way to do this.
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.
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)
For Python 3.x, 'reload' must be imported using:
from importlib import reload
Hope it helps. Of course it is for debug purposes.
Cheers.
I'd suggest use IPython autoreload extension.
./manage.py shell
In [1]: %load_ext autoreload
In [2]: %autoreload 2
And from now all imported modules would be refreshed before evaluate.
In [3]: from x import print_something
In [4]: print_something()
Out[4]: 'Something'
# Do changes in print_something method in x.py file.
In [5]: print_something()
Out[5]: 'Something else'
Works also if something was imported before %load_ext autoreload
command.
./manage.py shell
In [1]: from x import print_something
In [2]: print_something()
Out[2]: 'Something'
# Do changes in print_something method in x.py file.
In [3]: %load_ext autoreload
In [4]: %autoreload 2
In [5]: print_something()
Out[5]: 'Something else'
There is possible also prevent some imports from refreshing with %aimport
command and 3 autoreload strategies:
%autoreload
- Reload all modules (except those excluded by %aimport) automatically now.
%autoreload 0
- Disable automatic reloading.
%autoreload 1
- Reload all modules imported with %aimport every time before executing the Python code typed.
%autoreload 2
- Reload all modules (except those excluded by %aimport) every time before executing the Python code typed.
%aimport
- List modules which are to be automatically imported or not to be imported.
%aimport foo
- Import module ‘foo’ and mark it to be autoreloaded for %autoreload 1
%aimport -foo
- 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.
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.