Django 1.8
由于没有明显的原因,包的模块中定义的全局变量在其初始赋值和延迟函数调用之间被替换。
使用django-admin startproject
创建最小Django项目。添加了django-admin startapp simplelib
的新空应用程序。新应用simplelib
已添加到项目INSTALLED_APPS
的{{1}}。
Bellow是唯一添加的代码:
settings.py
使用# content of myproject.simplelib.__init__.py
from django.db import models
from django.db.models.signals import class_prepared
def myhandler(sender, **kwargs):
print 'models from myhandler: {}'.format(models)
def direct_call():
print 'models from direct_call: {}'.format(models)
class_prepared.connect(myhandler)
print 'models from top namespace: {}'.format(models)
direct_call()
运行项目时,会生成以下输出:
manage.py runserver
参见,当调用信号处理函数时,models from top namespace: <module 'django.db.models' from '/home/<snip>/Projects/Python/django-projects/lib/python2.7/site-packages/django/db/models/__init__.pyc'>
models from direct_all: <module 'django.db.models' from '/home/<snip>/Projects/Python/django-projects/lib/python2.7/site-packages/django/db/models/__init__.pyc'>
models from myhandler: <module 'simplelib.models' from '/home/<snip>/Projects/Python/django-projects/myproject/simplelib/models.pyc'>
^^^^^^^^^^^^^^^^
全局变量被更改。
没有其他项目的代码。它必须由Django本身改变。
注意:上述效果仅适用于modules
tuple开头simplelib
的情况。最后添加时,INSTALLED_APPS
仍会按预期指向models
。
知道这里有什么?
答案 0 :(得分:1)
这是正常的Python行为。
导入子模块时,该子模块将设置为父模块上的属性。在这种情况下,导入simplelib.models
时,会在父模块models
上设置simplelib
子模块。父模块名称空间与该模块的__init__.py
全局名称空间相同。这将覆盖旧值。
如果您将simplelib
作为INSTALLED_APPS
中的第一个条目,其models
子模块将是Django导入的第一个模型模块。在任何模型触发simplelib.models
信号之前,这将替换class_prepared
属性。另一方面,如果您将simplelib
放在INSTALLED_APPS
的末尾,Django将加载simpellib.models
作为最后一个模型模块。之前导入的任何模型都会在导入class_prepared
之前以及在使用子模块替换simplelib.models
属性之前触发models
信号。