我正在使用Django并且一直使用Django shell。令人讨厌的部分是当Django服务器重新加载代码更改时,shell不会,因此每次我对我正在测试的方法进行更改时,我需要退出shell并重新启动它,重新导入所有模块我需要,重新初始化我需要的所有变量等。虽然iPython历史记录在此节省了大量的输入,但这仍然很痛苦。有没有办法让django shell自动重载,就像django开发服务器一样?
我知道reload(),但是我导入了很多模型并且通常使用from app.models import *
语法,所以reload()没什么帮助。
答案 0 :(得分:42)
查看django-extensions项目提供的manage.py shell_plus命令。它将在shell启动时加载所有模型文件。并自动加载你的任何修改,但不需要退出,你可以直接打电话
答案 1 :(得分:37)
我建议使用IPython autoreload extension。
./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排除的模块除外) 现在。
%autoreload 0
- 禁用自动重新加载。
%autoreload 1
- 每次执行前重新加载所有使用%aimport导入的模块 键入的Python代码。
%autoreload 2
- 每次重新加载所有模块(%aimport排除的模块除外) 在执行键入的Python代码之前。
<强>%aimport 强>
- 列出要自动导入或不导入的模块 进口。
%aimport foo
- 导入模块'foo'并将其标记为自动重载为%autoreload 1
%aimport -foo
- 将模块'foo'标记为不自动重载。
这通常适合我的使用,但有一些洞穴:
- 替换代码对象并不总是成功:将类中的@property更改为普通方法或将方法更改为成员变量可能会导致问题(但仅限于旧对象)。
- 不会升级在重新加载之前从模块中删除的功能(例如,通过猴子修补)。
- C扩展模块无法重新加载,因此无法自动重载。
答案 2 :(得分:29)
我建议像东维明一样使用django-extensions项目。但是,不要只使用'shell_plus'管理命令,而是使用:
manage.py shell_plus --notebook
这将在您的网络浏览器上打开一个IPython笔记本。在单元格,导入等中编写代码并运行它。
更改模块时,只需单击笔记本菜单项“Kernel-&gt; Restart”
即可你去了,你的代码现在使用你修改过的模块。
答案 3 :(得分:26)
我的解决方法是编写代码并保存到文件中,然后使用:
python manage.py shell&lt; test.py
所以我可以进行更改,再次保存并运行该命令,直到我解决了我想要解决的问题。
答案 4 :(得分:25)
似乎关于这个主题的普遍共识是python reload()糟透了,没有好办法做到这一点。
答案 5 :(得分:4)
如果没有一些技巧,Reload()在Django shell中不起作用。你可以专门检查这个线程na和我的答案:
How do you reload a Django model module using the interactive interpreter via "manage.py shell"?
答案 6 :(得分:4)
我解决这个不方便的方法如下。我正在使用IPython。
from importlib import reload
对于 Python 3.x ,&#39;重新加载&#39;必须使用以下方式导入:
User.where('address IS ? AND address IS ?', nil, nil)
希望它有所帮助。当然这是出于调试目的。
干杯。
答案 7 :(得分:1)
您可以设置管理命令like so,并且每次都重新运行,而不是从Django shell运行命令。
答案 8 :(得分:1)
结合使用 2 个答案,我想出了一个简单的单行方法。
您可以使用 -c 运行 django shell,它会运行您传递的命令,但是它会在代码运行后立即退出。
诀窍是设置您需要的内容,运行 code.interact(local=locals()) 然后从您传递的代码中重新启动 shell。像这样:
python manage.py shell -c 'import uuid;test="mytestvar";import code;code.interact(local=locals())'
对我来说,我只想要丰富的图书馆的检查方法。只有几行:
python manage.py shell -c 'import code;from rich import pretty;pretty.install();from rich import inspect;code.interact(local=locals())'
最后上面的樱桃是别名
alias djshell='python manage.py shell -c "import code;from rich import pretty;pretty.install();from rich import inspect;code.interact(local=locals())"'
答案 9 :(得分:0)
不完全是你想要的,但我现在倾向于建立自己的管理命令来测试和摆弄东西。
在命令中,您可以按照自己想要的方式设置一堆本地人,然后放入交互式shell。
import code
class Command(BaseCommand):
def handle(self, *args, **kwargs):
foo = 'bar'
code.interact(local=locals())
没有重新加载,但是以交互方式测试django功能的简单且不那么恼人的方式。
答案 10 :(得分:0)
将shell_plus与ipython配置一起使用。这将在shell_plus自动导入任何内容之前启用autoreload
。
pip install django-extensions
pip install ipython
ipython profile create
编辑您的ipython个人资料(~/.ipython/profile_default/ipython_config.py
):
c.InteractiveShellApp.exec_lines = ['%autoreload 2']
c.InteractiveShellApp.extensions = ['autoreload']
打开一个外壳-请注意,您不需要包含--ipython
:
python manage.py shell_plus
现在,SHELL_PLUS_PRE_IMPORTS
或SHELL_PLUS_POST_IMPORTS
(docs)中定义的任何内容都会自动重新加载!