如何在django shell中重装模块?

时间:2010-09-22 18:02:50

标签: python django ipython

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

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

11 个答案:

答案 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())"'

现在,如果我启动我的 shell 并说,想要检查表单类,我会得到这个漂亮的输出: enter image description here

答案 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_IMPORTSSHELL_PLUS_POST_IMPORTSdocs)中定义的任何内容都会自动重新加载!