3

我目前正在使用Django==1.7.1. 我有一些具有相同模块名称的可重用应用程序。这也使模型的应用程序标签相同。这实际上是矛盾的。您不能INSTALLED_APPSsettings文件中的不同库中使用两个具有相同名称的模块。

我通过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

似乎什么都没有改变。尽管我删除了所有迁移文件,但它甚至没有创建初始文件。我认为,它没有看到模型。每当我从我的应用程序配置中删除覆盖的标签字段时,模型就会再次被发现。所以,不要认为我的模型位置是错误的。

这也可能是错误,我不知道。但是,如果我做错了什么,那会是什么?

谢谢!

4

1 回答 1

3

我深入回顾了大部分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.Cause,不会有 app 标签与 app config 标签相同的模型。这是导致问题的有问题的部分之一。这还不够,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 配置中定义的 app_label 值改变。

于 2014-12-18T12:44:28.280 回答