一尘不染

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

django

我知道如何在常规Python解释器会话中重新加载常规Python模块。这个问题记录了如何做得很好:

如何卸载(重新加载)Python模块?

由于某种原因,我在Django的“ manage.py shell”解释器会话中很难做到这一点。要重现我的问题,请在此处启动基本的Django教程:

编写第一个Django应用程序,第1部分

创建“ polls”应用程序和“ Poll”类后,通过“ manage.py shell”启动解释器,然后将“ polls”应用程序导入其中。

import polls.models as pm

创建一个新的“ Poll”对象:

p = pm.Poll()

到目前为止一切都很好。现在回到你的源代码并添加任何任意方法或属性。例如,我添加了:

def x(self):
    return 2+2

现在回到解释器并“重新加载”模块:

reload(pm)

现在尝试使用你的新方法或属性:

p1 = pm.Poll()
p1.x()

你会收到以下消息:

'Poll' object has no attribute 'x'

是什么赋予了?我还尝试过重新运行import命令,使用不同的语法导入模块,删除对任何“ Poll”对象或“ Poll”类的所有引用。我还使用IPython解释器和普通的Python(v2.6)解释器进行了尝试。似乎没有任何作用。

在常规的解释器会话中将相同的技术与任意Python模块配合使用非常有效。我似乎无法在Django的“ shell”会话中使用它。

顺便说一下,如果有什么不同,我将在Ubuntu 9.04机器上执行此操作。


阅读 655

收藏
2020-03-27

共1个答案

一尘不染

好吧,我想我必须回答这个问题。问题在于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
我将所有这些都放在Django站点根目录中的一个名为reloadmodels.py的单独文件中。使用IPython,我可以通过运行以下命令重新加载所有内容:

%run ~/mysite/reloadmodels.py

2020-03-27