3

Django プロジェクトに 2 つのアプリがインストールされています...

Contacts Package
  Models.py
     - class Contact 

Homes Package
 Models.py
     - class House

クラスHouseには と呼ばれるモデル メソッドがget_contactあり、このメソッドでは連絡先やフィルターなどをインポートします(重要ではありません)

私の質問: House は Contacts に依存するようになりました。つまり、Contact アプリがなければ House アプリをインストールできなくなりました。この家にもかかわらず、連絡先がなくても存在できるはずです。Python では、(フレームワーク Django のコンテキストでは) Python の人々はこれにどのように対処しますか?

より良い方法はありますか?

4

3 に答える 3

4

Contactsパッケージの使用がHouse単一のメソッドに限定されている場合は、インポートをメソッド内に配置して例外をキャッチします。

def foo(self):
    try:
        from Contacts.Models import Contact
    except ImportError:
        return
    ... use Contact here

または、モジュールの上部にインポートを配置することもできますが、使用できない場合は None に設定します。

try:
    from Contacts.Models import Contact
except ImportError:
    Contact = None


...
if Contact is not None:
    ... use Contact ...

より純粋な OOP ルートに進みたい場合は、Zope3 アダプターを使用できますが、それは、1 つのパッケージへの依存関係を他のグループへの依存関係と交換したことを意味します。あなたが説明した問題に対してはやり過ぎである可能性がありますが、この解決策を調査したい場合は、このブログ投稿を参照してください。

これを試した場合に直面する実際の問題はIContactProvider、House クラスにフェッチできるようなインターフェイスを定義する必要があることだと思います。そのインターフェイスはどこかに存在する必要があり、その場所が Contacts パッケージである場合でも、そのパッケージをインストールする必要があります。ある種の一般IContactProvider的な実装といくつかの特定の実装が必要な場合、これはその問題を処理する良い方法になる可能性があります。

于 2013-04-29T09:12:54.380 に答える
1

Django では、実行時にモデルを名前で動的に取得できます。これは、循環インポートを回避するための適切なオプションです。関数にはdjango.db.models.get_model()次のシグネチャがあります。

def get_model(self, app_label, model_name, seed_cache=True, only_installed=True)

したがって、Houseモデル内のコードは次のようになります

from django.db.models import get_model
Contact = get_model('contacts', 'Contact')
于 2013-04-29T11:22:41.010 に答える
1

シグナルと ProxyModels としての Django (そして、より良い解決策がない場合、Python にはモンキーパッチがあります)。アプリを分離しておくために私が通常行うことは (もちろん、それが理にかなっている場合)、プロジェクト固有の統合レイヤーとして使用する「メイン」の django アプリを用意することです。この場合、(ForeignKey などの) House"ハードワイヤード" 依存関係がないと仮定すると、メソッドを追加する場所にContactProxyModel を定義します。Houseget_contact

于 2013-04-29T10:57:12.063 に答える