6

Djangoと相互作用するアプリでインポートの問題が発生するのは非常に簡単です。私の質問は簡単です:

循環インポートを最小化するための受け入れられたプロセスは何ですか、または誰かが共有することをいとわないこれらを減らすために受け入れられたコーディング標準を思いついたことがありますか?

標準化できる優れた原則を探しています。

モデル

class Program(models.Model):
    group = models.ForeignKey(Group, related_name="%(app_label)s_%(class)s_related") 

vs

class Program(models.Model):
    group = models.ForeignKey('auth.Group', related_name="%(app_label)s_%(class)s_related") 

ビュー:

class ProgramDetailView(DetailView):
    """Detail view of the EEP Program"""

    def get_queryset(self):
        """Narrow this based on your company"""
        from apps.company.models import Company
        company = Company.objects.get(name="foo")
        return Program.objects.filter(company = company)

vs(これは問題を引き起こす傾向があります。。

from apps.company.models import Company
class ProgramDetailView(DetailView):
    """Detail view of the EEP Program"""

    def get_queryset(self):
        """Narrow this based on your company"""
        company = Company.objects.get(name="foo")
        return Program.objects.filter(company = company)

これに伴う問題は、あなたがいたるところにたくさんの輸入をする傾向があるということです。

4

2 に答える 2

1

何年にもわたって、私はWebアプリの開発方法に関する観察に基づいて、いくつかのパターンを標準化しました。

モジュール性とコードの再利用に関するあなたの基準はわかりませんが、次の簡単なルール/パターンは、かなり大規模なプロジェクトで大いに役立ちました。

私のモデルの多くがいくつかの共通の属性を共有していることに気づきました。たとえば、主キーとして、単純な自動インクリメント整数の代わりにUUIDを使用することを好みます。

だから私はこの抽象的なモデルを持っています。

class UUIDModel(models.Model):
    id = UUIDField(primary_key=True, auto=True)  # There are many implementation of this on the web. Choose your favorite.

    class Meta:
        abstract = True

私のモデルの多くは、の概念を必要としていactivationます。だから私はこれに似た別の抽象的なモデルを持っています:

class ActivatedModel(Model):
    is_active = models.BooleanField(default=False)

    def activate(self, save=True):
        if self.is_active:
            raise Exception('Already activated')
        self.is_active = True
        if save:
            self.save()

    class Meta:
        abstract = True

作成時間と変更を追跡するために、または何かがfinalizedさらに変更できる場合とできない場合などに、私が使用する抽象的なモデルは他にもたくさんあります。

これらの抽象的なモデルはすべてcoreアプリに存在します。これが私がそれを呼ぶ方法です。アプリとは別にcore、私はアプリを持っていtasksます。このアプリは、私がよく使うセロリtasksとのインターフェースを強化する抽象的なモデルを提供します。

アプリはアプリtasksからモデルをインポートできますcoreが、その逆はできません。

mmsマルチメディアの作成と変換(サムネイルなど)を処理するアプリもあります。以前のmmsアプリからモデルをインポートできます。したがって、現在のインポート関係は次のとおりです。コア->タスク->mms。

私が作成する他のすべてのアプリは、私が取り組んでいる現在のプロジェクトに固有のものであり、以前のアプリに基づいて構築されています。ですから、基本的には「一方向インポート」と呼べるようにしています。

そして、私はこれに似たモデルになります:

# models.py of an app called  "articles"

from core.models import UUIDModel, ActivatedModel
from tasks.models import ManagedTasksModel

class Article(UUIDModel, ActivatedModel, ManagedTasksModel):
    title = models.CharField()
    # blah...

アプリが大きくなりすぎる場合は、上記のルールに従ってmodels.pyモジュールを小さなモジュールに分割することで、アプリを「マイクロ管理」します。私はこれが私のニーズのほとんどをカバーしていることを知りました。

クラスベースのビューについてコメントすることはできません。正直なところ、私はそれらが好きではなく、ほとんどの場合、コードを少なくするのではなく、多く書くようになるからです。それぞれ自分自身に。私はヘルパーユーティリティ関数を使用し、ビュー関数内でコンテキストプロセッサなどをうまく利用することを好みます。

私の答えがあなたの質問の文脈の中にあったことを願っています。

編集:私はちょうどあなたの使用法がrelated_nameそのオプションのポイントを逃していると思うことに気づきました。次の例を参照してください。

class Message(models.Model):
    sender   = models.ForeignKey(User, related_name='messages_sent')
    receiver = models.ForeignKey(User, related_name='messages_received')
    body     = models.Textfield()

上記のモデルを使用すると、これを行うことができます。これは非常に読みやすいです。

u1 = User.objects.get(...)
received = u1.messages_received.all()

...そしてそれはこの関係の機能的な目的を表しています。したがってrelated_name、一意の関連する名前を持つために使用されるだけではありません。

于 2012-09-03T21:44:31.970 に答える
1

ビューコードについて

アプリAのビューコードがアプリBのビューコードを循環インポートするような方法でインポートする可能性は低いと思います。
アプリAのビューで別のアプリBのビューコードを使用している場合、そのコードはviews.pyファイルに属している必要がありますが、utils.py(または同様の)ファイルに属している必要があります。

アプリAのモデルコードがアプリBのビューコードをインポートする可能性はさらに低いため、アプリBのビューコードでアプリAのモデルコードのトップレベルのインポートを使用してもまったく問題ありません。

モデルコードについて

ただし、おっしゃるようにForeignKey、異なるアプリのモデル間に関係があると、循環インポートにつながる可能性があります。
挑戦するアドレスに文字列表記を使用しForeignKey、Djangoのドキュメントにあるように:

まだ定義されていないモデルにリレーションシップを作成する必要がある場合は、モデルオブジェクト自体ではなく、モデルの名前を使用できます。

これはManyToManyOneToOne関係にも機能します。

受け入れられた基準の存在について

本当に存在するとは思いませんが、django.contribアプリを見ることは関係があるのではないかと思いました。モデルのインポートを使用します。

あなたはチェックアウトしたいかもしれません:

人気のあるアプリも同じ機能を使用します。

social_authまた、これに関するバリエーションのソースを確認することもできます。

一般的な経験則では、可能な場合はモデルインポートを使用することになると思いますが、必要に応じて文字列表記を使用する準備をしてください。

于 2012-09-03T22:23:25.880 に答える