Django 1.8
由于没有明显的原因,包的模块中定义的全局变量被替换为初始赋值和延迟函数调用。
最小Django项目是用django-admin startproject创建的。添加了django-admin startapp simplelib的新的空应用程序。新的应用程序simplelib添加到INSTALLED_APPS of project的settings.py中。
Bellow是唯一添加的代码:
# 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'>
^^^^^^^^^^^^^^^^请参阅,当调用信号处理程序函数时,modules全局变量将被更改。没有其他项目的代码。它必须由Django自己改变。
注意:上面描述的效果只适用于simplelib放在INSTALLED_APPS元组的开头。当添加到末尾时,models仍然指向django.db.models,正如预期的那样。
知道这是怎么回事吗?
发布于 2016-11-02 22:38:20
这是正常的Python行为。
导入子模块时,该子模块设置为父模块上的属性。在本例中,导入simplelib.models时,在父模块simplelib上设置models子模块。父模块命名空间与该模块的__init__.py全局命名空间相同。这将覆盖旧值。
如果将simplelib作为INSTALLED_APPS中的第一个条目,则它的models子模块将是Django导入的第一个模型模块。这将在任何模型触发simplelib.models信号之前替换class_prepared属性。另一方面,如果将simplelib放在INSTALLED_APPS的末尾,Django将加载simpellib.models作为最后一个模型模块。在此之前导入的任何模型都将在导入class_prepared信号之前以及在models属性被替换为子模块之前触发simplelib.models信号。
https://stackoverflow.com/questions/40390781
复制相似问题