我知道如何在常规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机器上执行此操作。
好吧,我想我必须回答这个问题。问题在于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