2009-07-21 1 views
80

私のスーパーバイザーからの指示: "models.pyにはロジックを入れないでください。ここから、データベースにアクセスするためのクラスとしてのみ使用して、モデルクラスを使用する外部クラスにすべてのロジックを保持してください。彼らを包みなさい。models.pyが巨大化している、それを解消する最善の方法は何ですか?

私はこれが間違ったやり方だと感じます。私は、ファイルを小さく保つためにモデルから論理を取り除くことは悪い考えです。ロジックがモデル内で最善の場合、それはファイルサイズに関係なく実際に行われるべき場所です。

includeを使用する簡単な方法はありますか? PHPでは、私は監督に、models.py他の場所のモデルクラスをincludeしていることを提案したいと思います。概念的には、これによりモデルに必要なすべてのロジックを持たせることができますが、ファイル数を増やすことでファイルサイズを抑えることができます(競合などのリビジョン管理の問題が少なくなります)。

したがって、models.pyファイルからモデルクラスを削除する簡単な方法がありますが、モデルはまだすべてのDjangoツールで使用できますか?あるいは、 "large" models.pyファイルの一般的な問題とは全く異なった、しかしエレガントな解決策がありますか?どんな入力も感謝します。

+6

あなたはimport文を知っていますか? PS。 – balpha

+6

PS。私はそれを攻撃的に意味するものではなく、あなたがどこにいるのかを知りたいだけです。 – balpha

+0

はい、私はdjangoの管理ツールがimport文を使ってモデルを引きつけるだけで動作するかどうかはわかりませんでした。私はむしろdjangoのツールがうまく動作しないことを知るために、普通のoleのインポートを試してみるのに多くの時間を費やすよりも、ここで尋ねたいと思う。私はPythonとDjangoのほうが新しいと認めています。だから、私はおそらくimportステートメントの単純な理解にすぎないでしょう... – Eddified

答えて

61

Djangoは、1つの大きなアプリケーションではなく、多数の小さなアプリケーションを構築できるように設計されています。

大規模なアプリケーションの中には、多くの小さなアプリケーションが無料で苦労しています。

models.pyが大きければ、あまりにも多くのことをしています。やめる。リラックス。分解する。

小さな、潜在的に再利用可能な小さなアプリケーションコンポーネントまたは小片を見つけます。 実際にはを再利用する必要はありません。潜在的に再利用可能であると考えてください。

あなたのアップグレードパスを検討し、いつか置き換えたいアプリケーションを分解してください。 実際にはを置き換える必要はありませんが、将来的にはよりクールなものに置き換えられる可能性のあるプログラミングのスタンドアロンの「モジュール」とみなすことができます。

約12個のアプリケーションがあります。それぞれmodel.pyは、約400行以下です。彼らはすべて約半数の個別クラス定義に集中しています。 (これらは厳しい制限ではなく、私たちのコードに関するものです。)

私たちは早く分解します。

+1

がポイント上にあります。非自明なWebアプリケーションは、いくつかの小さな「アプリ」になります。貢献と他の一般的なアプリのヒントを取る、ユーザー認証は1つのアプリケーションです、タグ付けは別のものです、ユーザープロファイルもう1つ、等 – Javier

+4

これは "正しい"方法であり、知っているが、それは何ではない私は探していた。私が探していた答えの種類を知る方法がない場合は、お詫び申し上げます。:) – Eddified

+0

@例外:あなたがこれをしなければ、悪化するだけです。今すぐ分割を開始してください。 –

93

モデルクラスにはモデルで操作するメソッドが含まれているのは当然です。メソッドbook.get_noun_count()を使ってBookモデルを持っていれば、それがどこに属しているのですか?メソッドが実際に他のパッケージに属していない限り、 "get_noun_count(book)"と書く必要はありません。 (例えば、AmazonのAPIにアクセスするためのパッケージが「get_amazon_product_id(book)」である場合)

Djangoのドキュメンテーションでモデルを1つのファイルに入れることを示唆したときにひどくなり、最初から数分かかりましたそれを適切なサブパッケージに分割する方法を理解する。

site/models/__init__.py 
site/models/book.py 

__init__.py次のようになります。

from .book import Book 

ので、私はまだ "帳をインポートsite.modelsから" 書くことができます。

次のみDjangoの1.7より前のバージョンのために必要とされる

、唯一のトリックはあなたが原因ジャンゴのバグのため、明示的に各モデルのアプリケーションを設定する必要があることです https://code.djangoproject.com/ticket/3591

見ます:アプリケーション名がモデルパスの最後から3番目のエントリであるとみなします。 "site.models.Book"は正しい "site"になります。 "site.models.book.Book"は、アプリケーション名が "models"であると判断します。これはDjangoの部分のかなり不快なハックです。おそらくインストールされたアプリケーションのリストを検索してプレフィックスの一致を調べるべきです。

class Book(models.Model): 
    class Meta: app_label = "site" 

これを一般化するためにおそらくベースクラスまたはメタクラスを使用することができますが、私はそれをまだ心配していません。

+2

+1私はこれを成功に使用しました。 S. Lottは複数のアプリの中では良いアイデアだと思っていますが、これは今や現在の解決策です。 –

+0

これはこれを行う方法です。 Djangoのウェブサイトに詳しい情報があります:http://code.djangoproject.com/wiki/CookBookSplitModelsToFiles –

+0

@Alexander Ljungberg:これはアプリケーションを分割するよりも簡単だとは思いません。アプリは簡単に元の 'models.py'から分割することができます。しばしば、urls.py、views.py、tests.py、およびmodels.pyから切り取って貼り付けるだけです。 –

4

多くの可能性のある問題があります。

  • 複数のモデルの別々のファイルに入れて、同じファイル

    に:ここでの答えと、いくつかの可能性があります。依存関係がある場合は、インポートを使用して 追加モデルを取得します。 models.py

  • 余分なロジック/ユーティリティ機能は、別々のファイルに余分なロジックを入れてください。

  • データベース

    からいくつかのモデルインスタンスを選択するための

    静的メソッドは、別のファイルに新しいManagerを作成します。明らかにモデル

    保存に関連

  • 方法、__unicode__とはget_absolute_urlがその例です。

関連する問題