编程语言
首页 > 编程语言> > python-Django 1.7-具有自定义应用程序标签的模型发现和应用程序配置

python-Django 1.7-具有自定义应用程序标签的模型发现和应用程序配置

作者:互联网

我目前正在使用Django == 1.7.1.我有一些具有相同模块名称的可重复使用的应用程序.这也使模型的应用程序标签相同.这实际上是矛盾的.您不能在设置文件的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 config中更改标签,模型app_label也不会更改.因此,Django认为,模型和自定义应用程序配置适用于不同的应用程序.我认为,这是一个错误.

在django.apps.registry中,填充方法中包含以下几行:

...
            # 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标签与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 config中定义的app_label值进行更改.

标签:django-migrations,django-1-7,python,django
来源: https://codeday.me/bug/20191120/2047822.html