1

膨大な量のサブアプリケーションを備えた巨大な Django アプリを手に入れました。現在、私は 1 つのサブアプリでモデルの再加工に取り組んでいるので、問題が発生しました。モデルを操作するための分離された醜い関数が大量にあります。基本的には、次のようなものです。

def get_some_things(...):
 def postprocess(...):
  pass
 def preprocess(...):
  pass
 preprocess(...)
 x = MyModel.objects.....get(1)
 return postprocess(x, ...)

そして、私はこのような関数をたくさん持っていますが、それは本当に醜いです! そして、それは現在のコード(のようなDatabaseAccessor.get_db().django_kitty().get_some_things(...))で使用されています。したがって、私の考えは、開発者がこれらの関数を次のように使用できるようにすることでした。

MyModel.get_some_things(...)

または、次のようにします。

MyModel.objects.get_some_things(...)

しかし!関数が多すぎて、model.py 内に書ききれません。だから、私はいくつかのアイデアを得ました:

  1. model_mymodel.py を作成し、モデル内のすべての関数と静的関数を使用してモデルを定義します。しかし...よくわかりませんが、モデルクラスに入れる必要がありますか?
  2. mymodel_manager.py を作成し、mymodel のモデル マネージャーを作成し、ここで関数を定義します。しかし...私の「関数」のいくつかは、辞書、リスト、または数値だけを返す必要があります。モデル マネージャが QuerySet 以外のものを返せるようにするのはイデオロギー的に間違っているのでしょうか?
  3. __getattr__MyModel クラスをオーバーライドしfunctions_common.pyfunctions_things.pyなどのモジュールを動的にロードし、収集した関数を辞書に格納し、必要に応じて呼び出しますか?
4

3 に答える 3

5

モデルに多くの独自のメソッドが必要な場合、巨大なモデル定義を持つことは代償になります。何らかの理由で機能を他のファイルに分割したい場合 (または、実際に役立つもののために共通の機能を共有したい場合) は、ミックスイン アプローチを使用できます。

#mymodel.py
class MyModelMixin:
    def django_kitty(self, ...):
        pass
    def postprocess(self, ...):
        pass
    def preprocess(self, ...):
        pass

#models.py
from mymodel import MyModelMixin

class MyModel(models.Model, MyModelMixin):
    pass

あなた自身の提案について:

1 - モデルごとに個別のファイルが必要な場合は、次のアプローチを使用できます。

myapp/
    models/
        __init__.py
            from mymodel import MyModel
        mymodel.py

モデルごとに app_label を明示的に設定する必要があることに注意してください。

#mymodel.py
class MyModel(models.Model):
    ...
    class Meta:
        app_label = 'myapp'

2 - マネージャー メソッドの戻り値の型は無関係です。マネージャーとモデルの違いは、テーブルレベルの機能をそれぞれ分離することです。

3 - 不必要な魔法のように聞こえますが、オーバーライドModel.__getattr__は骨の折れる作業です。

于 2012-12-16T20:24:29.650 に答える
1

オプション2のように聞こえます。

モデルマネージャメソッドがQuerySetを返さないことには何の問題もありません。

于 2012-12-16T20:21:39.207 に答える