3

私は現在使用して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これで、これらのアプリ構成をモジュールではなくmy に追加できます。競合は解決されるだけです。その時点まではすべて問題ありません。

これが私の問題です。のラベルをオーバーライドするとAppConfig、そのモジュール内のモデルが によって検出されませんDjango。走ると・・・

python manage.py makemigrations

何も変わっていないようです。すべての移行ファイルを削除しても、最初の移行ファイルは作成されませんでした。私は、それはモデルを見ていないと思います。アプリ構成から上書きされたラベル フィールドを削除するたびに、モデルは再び検出可能になります。したがって、私のモデルの場所が間違っているとは思わないでください。

これもバグかもしれませんが、わかりません。しかし、私が何か間違ったことをしている場合、それは何でしょうか?

ありがとう!

4

1 に答える 1

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これは、問題を引き起こす問題のある部分の 1 つです。これだけでは不十分で、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 値によって変更する必要があります。

于 2014-12-18T12:44:28.280 に答える