我知道如何在常规Python解释器会话中重新加载常规Python模块.这个问题记录了如何做得很好:
出于某种原因,我在Django的"manage.py shell"解释器会话中遇到了麻烦.要重新创建我的问题,请启动此处的基本Django教程:
创建"民意调查"应用程序和"民意调查"类后,通过"manage.py shell"启动解释器并将"民意调查"应用程序导入其中.
import polls.models as pm
Run Code Online (Sandbox Code Playgroud)
创建一个新的"民意调查"对象:
p = pm.Poll()
Run Code Online (Sandbox Code Playgroud)
到目前为止一切顺利.现在回到您的源代码并添加任意方法或属性.例如,我添加了:
def x(self):
return 2+2
Run Code Online (Sandbox Code Playgroud)
现在回到解释器并"重新加载"模块:
reload(pm)
Run Code Online (Sandbox Code Playgroud)
现在尝试使用您的新方法或属性:
p1 = pm.Poll()
p1.x()
Run Code Online (Sandbox Code Playgroud)
你会收到这条消息:
'Poll' object has no attribute 'x'
Run Code Online (Sandbox Code Playgroud)
是什么赋予了?我还尝试重新运行import命令,使用不同的语法导入模块,删除对任何"Poll"对象或"Poll"类的所有引用.我也尝试过使用IPython解释器和普通的Python(v2.6)解释器.似乎没什么用.
在常规解释器会话中使用与任意Python模块相同的技术可以很好地工作.我似乎无法让它在Django的"shell"会话中工作.
顺便说一句,如果它有任何区别,我在Ubuntu 9.04机器上这样做.
Cha*_*uin 38
好吧,我想我必须回答这个问题.问题是Django将其模型缓存在一个名为AppCache的单例(类似单身的结构)中.基本上,要重新加载Django模型,您需要首先重新加载并重新导入存储在AppCache中的所有模型模块.然后你需要消灭AppCache.这是它的代码:
import os
from django.db.models.loading import AppCache
cache = AppCache()
curdir = os.getcwd()
for app in cache.get_apps():
f = app.__file__
if f.startswith(curdir) and f.endswith('.pyc'):
os.remove(f)
__import__(app.__name__)
reload(app)
from django.utils.datastructures import SortedDict
cache.app_store = SortedDict()
cache.app_models = SortedDict()
cache.app_errors = {}
cache.handled = {}
cache.loaded = False
Run Code Online (Sandbox Code Playgroud)
我将所有这些放在我的Django站点的根目录中名为reloadmodels.py的单独文件中.使用IPython我可以通过运行来重新加载所有内容:
%run ~/mysite/reloadmodels.py
Run Code Online (Sandbox Code Playgroud)
您还可以使用以下命令使用django-extensions项目:
manage.py shell_plus --notebook
Run Code Online (Sandbox Code Playgroud)
这将在您的Web浏览器上打开一个IPython笔记本,而不是IPython shell解释器.在那里编写代码并运行它.
更改模块时,只需单击网页菜单项'Kernel-> Restart'
现在重新运行代码会使用您修改过的模块.
我在2016年的解决方案(将来可能会更改)
1.安装django_extension
2.添加下一个设置:
SHELL_PLUS = 'ipython'
IPYTHON_ARGUMENTS = [
'--ext', 'autoreload',
]
Run Code Online (Sandbox Code Playgroud)
3,运行shell
./manage.py shell_plus
Run Code Online (Sandbox Code Playgroud)
模型实例
class Notification(models.Model):
........
@classmethod
def get_something(self):
return 'I am programmer'
Run Code Online (Sandbox Code Playgroud)
带壳
In [1]: Notification.get_something()
Out[1]: 'I am programmer'
Run Code Online (Sandbox Code Playgroud)
对模型进行了更改
@classmethod
def get_something(self):
return 'I am Python programmer'
Run Code Online (Sandbox Code Playgroud)
带壳
# shell does not display changes
In [2]: Notification.get_something()
Out[2]: 'I am programmer'
Run Code Online (Sandbox Code Playgroud)
在外壳中。这是魔术
# configure extension of ipython
In [3]: %autoreload 2
Run Code Online (Sandbox Code Playgroud)
带壳
# try again - all worked
In [4]: Notification.get_something()
Out[4]: 'I am Python programmer'
Run Code Online (Sandbox Code Playgroud)
再次进行更改
@classmethod
def get_something(self):
return 'I am full-stack Python programmer'
Run Code Online (Sandbox Code Playgroud)
带壳
# all worked again
In [5]: Notification.get_something()
Out[5]: 'I am full-stack Python programmer'
Run Code Online (Sandbox Code Playgroud)
缺点:1.需要手动运行代码
%自动重载2
因为django_extension 1.7不支持运行任意代码。可能在将来的版本中具有此功能。
笔记:
假设您的项目以这种方式设置
第一次加载
from bookstore.shelf.models import Books
Run Code Online (Sandbox Code Playgroud)
随后的重新加载
import bookstore;reload(bookstore.shelf.models);from bookstore.shelf.models import Books
Run Code Online (Sandbox Code Playgroud)
就我而言,上述解决方案都没有自行解决,这个线程本身也没有多大帮助,但在结合这些方法后,我设法在shell_plus中重新加载我的模型:
models.pyc清理Django模型缓存(像这里):
from django.db.models.loading import AppCache
cache = AppCache()
from django.utils.datastructures import SortedDict
cache.app_store = SortedDict()
cache.app_models = SortedDict()
cache.app_errors = {}
cache.handled = {}
cache.loaded = False
Run Code Online (Sandbox Code Playgroud)像这里重新加载模型
reload(project.app.models)
from project.app.models import MyModel
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
22015 次 |
| 最近记录: |