我目前正在使用Django==1.7.1
。我有一些具有相同模块名称的可重用应用程序。这也使得模型的应用标签相同。这实际上是矛盾的。您不能在INSTALLED_APPS
文件的settings
中的不同库中使用具有相同名称的模块。
我通过为模块添加AppConfig
并更改了标签(app_label)以解决冲突来解决这个问题;
#librarayX.my_module.apps.py
from django.apps import AppConfig
class ModuleAppConfig(AppConfig):
name = 'libraryX.my_module'
label = "X_my_module"
verbose_name = "my_module"
#librarayY.my_module.apps.py
from django.apps import AppConfig
class ModuleAppConfig(AppConfig):
name = 'libraryY.my_module'
label = "Y_my_module"
verbose_name = "my_module"
#settings.py
....
INSTALLED_APPS=[
...
'libraryX.my_module.apps.ModuleAppConfig',
'libraryY.my_module.apps.ModuleAppConfig',
...
]
...
现在,我可以将这些应用配置添加到我的INSTALLED_APPS
而不是模块中。冲突刚刚解决。到那时为止一切都还可以。
这是我的问题;当我覆盖AppConfig
的标签时,Django
不会发现该模块中的模型。我跑的时候;
python manage.py makemigrations
似乎没有任何改变。尽管我删除了所有迁移文件,但它甚至没有创建初始文件。我想,它没有看到模型。每当我从app app中删除重写的标签字段时,模型都可以再次被发现。所以,不要认为我的模型位置是错误的。
这也可能是错误,我不知道。但如果我做错了什么,它会是什么?
谢谢!
答案 0 :(得分:3)
我深深地回顾了Django
代码的大部分内容。应用程序配置中定义的自定义应用程序标签的应用程序中的模型(如问题中所示)不会由Django
导入。这是因为,即使您在app config中更改标签,模型app_label也不会更改。所以,Django认为,模型和自定义应用程序配置是针对不同的应用程序。我想,这是一个错误。
在django.apps.registry
中,populate method
中的行是:
...
# Load models.
for app_config in self.app_configs.values():
all_models = self.all_models[app_config.label]
app_config.import_models(all_models)
...
此部分还应导入app_config.name
中定义的模块中的模型,而不仅仅是app_config.label
。因为,应用程序标签与应用程序配置标签不同的模型。这是引起问题的问题部分之一。这还不够,还需要以某种方式更改模型app_label
。
这是我的解决方法。
我有一个抽象的应用程序配置,我的所有app配置都将继承。
from collections import OrderedDict
from django.apps import AppConfig, apps
class BaseAppConfig(AppConfig):
def __init__(self, *args, **kwargs):
super(BaseAppConfig, self).__init__(*args, **kwargs)
# Also import the models in modules defined in self.name
mod_path, _, cls_name = self.name.rpartition('.')
self.import_models(OrderedDict([(k, v) for k, v in apps.all_models[cls_name].iteritems() if self.name in v.__module__]))
def import_models(self, all_models):
if not self.models:
# Set the model app_labels as self.label
for m in all_models.values():
m._meta.app_label = self.label
super(BaseAppConfig, self).import_models(all_models)
这是一种不触及Django代码的解决方法。但是,我认为这个问题必须在Django中解决。模型app_labels也应该通过app config中定义的app_label值进行更改。