我目前正在使用 Django==1.7.1
。我有一些具有相同模块名称的可重用应用程序。这也使模型的应用程序标签相同。这其实是矛盾的。您不能在不同的库、settings
文件中的 INSTALLED_APPS
中使用同名的两个模块。
我通过为模块添加 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
似乎没有任何变化。尽管我删除了所有迁移文件,但它甚至没有创建初始文件。我认为,它没有看到模型。每当我从我的应用程序配置中删除覆盖的标签字段时,这些模型就会再次被发现。所以,不要认为我的模型位置是错误的。
这也可能是错误,我不知道。但如果我做错了什么,那会是什么?
谢谢!
最佳答案
我深入地回顾了大部分Django
代码。在应用程序配置中定义了自定义应用程序标签的应用程序中的模型,正如问题中给出的那样,不会被 Django
导入。这是因为,即使您更改应用配置中的标签,模型 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
。
解决方案:
这是我的解决方法。
我有一个抽象的应用配置,我所有的应用配置都将从中继承。
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_label 值进行更改。
关于python - Django 1.7 - 带有自定义应用程序标签的模型发现和应用程序配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27542607/