1

このアプリを django で設計する方法について、高度な質問があります。

ビューによって実行される同様の操作(作成、編集、保存など)を受けるモデルがいくつかあります。また、いくつかのユニークな操作があります。これらの操作の多くは同じであり、コードを繰り返したくありません。これらのモデルには、すべてのモデルに共通するいくつかのフィールドがあり、固有のフィールドもあります。これを設計する最良の方法は何ですか?

異なるモデルは異なるアプリになります。たとえば、モデルは学校、教会、レストランなどです。したがって、3 つのアプリがあります。これらのモデルは抽象クラスからサブクラス化されていると思います。ビューには、これら 3 つのアプリすべてで同じいくつかの操作もあります。共通のコード セットを記述する方法がわからず、これら 3 つのアプリに何かを継承させてから、必要に応じてカスタマイズします。いくつかのポインタ/方向が必要です。

編集: これらのモデルにはいくつかの共通フィールドがありますが、類似点はそこまでです。学校、イベント、またはニュース記事のモデルを作成できます (人間の視点とは完全に異なる場合があることがわかります)。必要に応じてこれらのモデルを追加または削除するため、別のアプリが必要です。これらすべてのアプリで呼び出す共通のものを作成する必要があるように思えますが、この共通のセットはモデルとビューに存在します (これをすべて行うフレームワークがほとんど必要だと思います)。

4

1 に答える 1

4

これはより概念的な答えです。

モデルが非常に似ている場合は、同じアプリに属する​​べきだと思います。私の推論は次のとおりです。私の意見では、アプリとは、一連の関連データと、そのデータに関連付けられたビジネス ロジックであり、場合によっては、そのデータをどのように表示するかについてのロジックでさえあります。したがって、モデルが非常に一般的である場合、データはある程度関連しているように見えるため、同じアプリにあるはずです。

ただし、私の経験では、1 つのアプリで 20 を超えるモデルを使用していた場合、一部のアプリは成長する可能性があります。これを 1 つのファイルで管理するのは非常に困難になる可能性がmodels.pyあるため、モデルをパッケージに分割するのが好きです。したがって、アプリの構造は次のようになります。

project/
  manage.py
  project/
    __init__.py
    settings.py
    ...
  app/
    __init__.py
    ...
    models/
      __init__.py
      ...

__init__.py唯一のことは、これを行う場合、モデルのファイルにすべてのモデルをインポートして__all__変数に含める必要があることです。そうすれば、モデルがパッケージとして構造化されていても、残りのコードではモジュールとして使用できます。

このアプローチの利点は、モデルがモジュール化されているため、保守がはるかに簡単になり、関連データが 1 か所に保持されることです。


ビジネス ロジックに関しては、継承によって多くの問題を処理する必要があると思います。いつでも複数のクラスから継承できます。これにより、それぞれに特定の機能セットを備えた一連の基本クラス/モデルを作成し、モデルの適切な基本クラスから継承することができます。これにより、可能な限り多くのコードを再利用できます。

別のアプローチは、メタクラスを使用することです。アイデアは、別のクラスのインスタンスを構築するクラスを定義することです。例:

class FooMetaClass(type):
    def __new__(cls, name, bases, dict):
        # do some logic
        return super(FooMetaClass, cls).__new__(cls, name, bases, dict)

class FooClass(object):
    __metaclass__ = FooMetaClass
    ...

したがって、いくつかの設定属性を に含めることができ、FooClassそれらの属性と場合によってはそれらの値に応じて、メタクラスはそのクラスのカスタマイズされたインスタンスを構築できるという考えです。この時点で、動的なものを生成することさえできます!

このアプローチは数回有用であることがわかりましたが、ほとんどの場合、サブクラス化で十分だと思います。


プレゼンテーションには、クラス ベースのビューが最適です。今年の DjangoCon で、Kenneth Love はクラスに基づくビューについて非常に良い話をしました。ここでスライドを見ることができます: https://speakerdeck.com/u/kennethlove/p/views-can-be-classyそしてうまくいけば、ビデオはすぐに公開されます. クラスベースのビューは、構造を除いて関数ベースのビューと同じです。

私のプロジェクトの多くで、私の見解の多くはほとんど同じであることを知っています。ビューの冒頭で何かが起こっていますが、これは多くのビューで非常に似ています。次に、ビューの中間/肉のセクションがあり、これは通常、各ビューに固有のものです。そして、コンテキスト ディクショナリを構築して応答を返すビューの最後のセクションがあります。そのため、私や他の多くの開発者が最終的に行っているのは、10 億個のヘルパー関数を用意することです。これらの関数を他のビューで呼び出して、特定の反復タスクを実行します。ただし、このアプローチはコードを読みにくくし、ヘルパー関数に多くのパラメーターを渡す必要があるため不要な抽象性を導入することがあり、最終的には正しくないと感じます。

ここで、クラス ベースのビューの出番です。これらは、ビューを複数の関数呼び出しに分割することを除いて、関数ベースのビューとまったく同じことを行います。したがって、1 つの関数がオブジェクトの取得を担当し、別の関数がコンテキストの構築を担当する、というようになります。次に、これらすべての関数を組み合わせると、関数ビューにあるものとほとんど同じコードが実行されます。ただし、これにより 1 つの大きな利点が得られます。ビューを継承できます。したがって、タスク a を実行するための 1 つの基底クラス ビューと、タスク b を実行するための別のビューを作成できます。したがって、両方のクラスを継承する別のビューを作成して、両方のタスクを実行できます。さらに、いくつかの基本ビューから継承すると、定義されている関数基本クラスを上書きできるため、柔軟性がさらに高まります。

これは、多くの同様のビューで共通のタスクを実行しながら、記述するコードの量を最小限に抑えるのに非常に役立つデザイン パターンです。


これにより、プロジェクト/アプリの構造に関するアイデアが得られることを願っています。

于 2012-09-14T05:52:35.260 に答える