如何在django shell中重新加载模块?
我正在使用Django并始终使用Django shell。 烦人的部分是,虽然Django服务器重新加载代码更改,但shell没有,所以每次我改变我正在testing的方法,我需要退出shell并重新启动它,重新导入所有模块我需要重新初始化我需要的所有variables等。虽然iPython的历史可以节省大量的input,但这仍然是一个痛苦。 有没有办法让Django的shell自动重装,就像django开发服务器一样?
我知道reload(),但是我导入了很多模型,并且通常使用from app.models import *
语法,所以reload()没有太大的帮助。
我推荐使用dongweiming的django-extensions项目。 但是,而不是只是'shell_plus'pipe理命令,使用:
manage.py shell_plus --notebook
这将在您的Web浏览器上打开IPython笔记本。 把你的代码写在一个单元格中,导入等等,然后运行它。
当你改变你的模块,只需点击笔记本菜单项“内核 – >重新启动”
在那里,你的代码现在正在使用你的修改模块。
看一下django-extensions项目提供的manage.py shell_plus命令。 它会在shell启动时加载所有的模型文件。 并自动重新加载你的任何修改,但不需要退出,你可以直接打电话在那里
似乎在这个主题上的普遍共识是,python reload()很糟糕,没有好办法做到这一点。
我的解决scheme是我写代码并保存到一个文件,然后使用:
python manage.py shell <test.py
所以我可以进行更改,保存并再次运行该命令,直到我修复了我正在尝试修复的任何内容。
我build议使用IPython自动重载扩展 。
./manage.py shell In [1]: %load_ext autoreload In [2]: %autoreload 2
从现在开始,所有导入的模块都将在评估之前刷新。
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'
也可以在%load_ext autoreload
命令之前导入某些内容。
./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'
使用%aimport
命令和3个自动%aimport
策略也可以防止某些导入刷新:
自动重载%
- 现在自动重新加载所有模块(%aimport排除的模块除外)。
%自动重载0
- 禁用自动重新加载。
%autoreload 1
- 在执行input的Python代码之前,每次重新加载使用%aimport导入的所有模块。
%autoreload 2
- 在执行input的Python代码之前,每次重新装入所有模块(%aimport除外的模块除外)。
%aimport
- 列出要自动导入或不导入的模块。
%aimport foo
- 导入模块“foo”并将其标记为自动重新载入以进行%autoreload 1
%aimport -foo
- 将模块“foo”标记为不能自动重新加载。
这通常适用于我的使用,但有一些cavetas:
- replace代码对象并不总是成功:将类中的@property更改为普通方法或将方法更改为成员variables可能会导致问题(但仅在旧对象中)。
- 在重新加载之前从模块中删除的function(例如,通过猴子修补)不会升级。
- C扩展模块无法重新加载,所以无法自动加载。
Reload()在没有一些技巧的Django shell中不起作用。 你可以检查这个线程na和我的答案具体:
如何通过“manage.py shell”使用交互式解释器重新载入Django模型模块?
我的这个不方便的解决scheme如下。 我正在使用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)
希望能帮助到你。 当然这是为了debugging目的。
干杯。
不用从Django shell运行命令,你可以像这样设置一个pipe理命令,并且每次都重新运行。
不完全是你想要的,但我现在倾向于build立自己的pipe理命令进行testing和摆弄东西。
在命令中,您可以按照自己想要的方式设置一堆本地人,然后放入交互式shell。
import code class Command(BaseCommand): def handle(self, *args, **kwargs): foo = 'bar' code.interact(local=locals())
没有重新加载,但一个简单而不那么恼人的方式来交互testingDjango的function。