如何在django shell中重装模块?

Mad*_*bat 73 python django ipython

我正在使用Django并一直使用Django shell.令人讨厌的部分是当Django服务器重新加载代码更改时,shell不会,因此每次我对我正在测试的方法进行更改时,我需要退出shell并重新启动它,重新导入所有模块我需要,重新初始化我需要的所有变量等.虽然iPython历史记录在此节省了大量的输入,但这仍然很痛苦.有没有办法让django shell自动重载,就像django开发服务器一样?

我知道reload(),但我导入了很多模型并且通常使用from app.models import *语法,所以reload()没有多大帮助.

bod*_*sog 50

我建议使用IPython autoreload扩展.

./manage.py shell

In [1]: %load_ext autoreload
In [2]: %autoreload 2
Run Code Online (Sandbox Code Playgroud)

从现在开始,所有导入的模块都会在评估之前刷新.

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'
Run Code Online (Sandbox Code Playgroud)

如果在%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'
Run Code Online (Sandbox Code Playgroud)

也有可能通过%aimport命令和3个自动重载策略阻止一些导入刷新:

自动重载%

  • 现在自动重新加载所有模块(%aimport排除的模块除外).

%autoreload 0

  • 禁用自动重新加载.

%autoreload 1

  • 每次执行键入的Python代码之前,每次重新加载使用%aimport导入的所有模块.

%autoreload 2

  • 每次执行键入的Python代码之前,每次重新加载所有模块(%aimport排除的模块除外).

%aimport

  • 列出要自动导入或不导入的模块.

%aimport foo

  • 导入模块'foo'并将其标记为自动重载为%autoreload 1

%aimport -foo

  • 标记模块'foo'不能自动重载.

这通常适合我的使用,但有一些洞穴:

  • 替换代码对象并不总是成功:将类中的@property更改为普通方法或将方法更改为成员变量可能会导致问题(但仅限于旧对象).
  • 在重新加载之前从模块中移除的功能(例如,通过猴子修补)不会升级.
  • C扩展模块无法重新加载,因此无法自动重载.

  • 如果您使用的是django的`/manage.py shell_plus`...。 (2认同)
  • 如果我想将其设置为默认行为,有没有办法使用“/manage.py shell_plus”自动执行此操作? (2认同)

小智 40

查看django-extensions项目提供的manage.py shell_plus命令.它将在shell启动时加载所有模型文件.并自动重载你的任何修改,但不需要退出,你可以直接在那里打电话

  • 我使用shell_plus,我的模型不是自动重装,我错过了什么? (38认同)
  • shell_plus不会重新加载模型,所以这不回答问题. (28认同)
  • shell_plus使用autoreload模块重新加载模块.键入'%load_ext autoreload'然后'%autoreload 2' - 请参阅https://ipython.org/ipython-doc/3/config/extensions/autoreload.html (11认同)
  • 如上所述,shell_plus不会重新加载模型. (4认同)
  • 应该更新此问题以标记答案. (2认同)
  • 也许我错过了一些东西,但是 shell_plus 没有为我重新加载任何东西。它在启动时加载所有模型,这很方便,但仅此而已。 (2认同)

mpa*_*paf 31

我推荐使用像dongweiming一样的django-extensions项目.但不仅仅是'shell_plus'管理命令,请使用:

manage.py shell_plus --notebook
Run Code Online (Sandbox Code Playgroud)

这将在您的Web浏览器上打开一个IPython笔记本.在单元格,导入等中编写代码并运行它.

更改模块时,只需单击笔记本菜单项"内核 - >重新启动"

你去了,你的代码现在使用你修改过的模块.

  • "只使用python笔记本"并不能解决OP的问题. (21认同)

Eri*_*rik 31

我的解决方案是我编写代码并保存到文件然后使用:

python manage.py shell <test.py

所以我可以进行更改,再次保存并运行该命令,直到我修复我正在尝试解决的问题.

  • 好看又简单。需要注意的是,在 py 文件的底部添加 ```exit()``` 以更简洁的方式退出 Django shell。谢谢。 (3认同)

Mad*_*bat 25

似乎关于这个主题的普遍共识是python reload()糟透了,没有好办法做到这一点.

  • 他的回答有多条评论说shell_plus不会重新加载模型 (3认同)

and*_*rov 8

shell_plus与 ipython 配置一起使用。这将autoreload在 shell_plus 自动导入任何内容之前启用。

pip install django-extensions
pip install ipython
ipython profile create
Run Code Online (Sandbox Code Playgroud)

编辑您的 ipython 配置文件 ( ~/.ipython/profile_default/ipython_config.py):

c.InteractiveShellApp.exec_lines = ['%autoreload 2']
c.InteractiveShellApp.extensions = ['autoreload']
Run Code Online (Sandbox Code Playgroud)

打开一个 shell - 请注意,您不需要包括--ipython

python manage.py shell_plus
Run Code Online (Sandbox Code Playgroud)

现在任何在SHELL_PLUS_PRE_IMPORTSor SHELL_PLUS_POST_IMPORTS( docs ) 中定义的东西都会自动重新加载!

请注意,如果您的 shell 在pdb.set_trace()您保存文​​件时处于调试器(ex )中,它可能会干扰重新加载。

  • 谢谢你的回答。不过你可能会注意到,我在 2010 年问过它。我很高兴知道八年后自动重新加载终于在 shell_plus 中工作了:) (2认同)

Roq*_*que 7

我对这种不便的解决方案如下。我正在使用 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)
Run Code Online (Sandbox Code Playgroud)

对于Python 3.x,必须使用以下命令导入“reload”:

from importlib import reload
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。当然,这是为了调试目的。

干杯。


Tom*_*ski 5

没有一些技巧,Reload()在Django Shell中不起作用。您可以检查此线程na和我的答案:

如何通过“ manage.py shell”使用交互式解释器重新加载Django模型模块?