0

私はいくつかのクラスを持つPythonアプリケーションを作成しました。それらの1つが次のようなものだったとしましょう(過度に単純化されていますが、機能のタイプを表現しようとしました):

class PythonXyz(object):

    def __init__(self):
        self.x = []
        self.y = []
        self.z = []

    def append(self, x, y):
        self.x.append(x)
        self.y.append(y)

    def get_x(self):
        return self.x

    def get_y(self):
        return self.y

    def get_z(self):
        return self.x + self.y

    def size(self):
        return len(self.x)

    def dump(self):
        #generate some output

    def do_some_complex_stuff(self, q):
        #lots of calculations and manipulation of the self.x and self.y lists.

    def save(self, filename):
        #some code that saves data to disk

    def load(self, filename):
        #some code that loads data from disk

アプリは動作したが使い勝手が悪かったので、ブラウザを貧乏人のGUIとして使用し、データベースの良さも利用できるように、アプリをdjangofyすることにしました。だから私は次のようなmodel.pyを作成しました:

class DjangoXyzModel(models.model):
    x = models.FloatField()
    y = models.FloatField()

また、PythonXYZクラスのload()メソッドとsave()メソッドを変更して、ファイルではなくデータベースを使用し、ブラウザーを介して機能するようにいくつかのビューを作成しました。

これで、3つのDjangoアプリが作成され、[編集]異なるdbスキーマ[/ edit]があり、それぞれにいくつかのモデルクラスを含む独自のmodels.pyファイルがあり、それに加えて、元のコードが別のフォルダーにあります。これはすべて非常に厄介になっていると感じており、すべてのPythonXyzメソッドをDjangoXyzModelクラスに完全に統合する方がはるかにクリーンな設計になると思いました。たとえば、次のようになります。

class DjangoXyzModel(models.model):
    x_db = models.FloatField()
    y_db = models.FloatField()

    def init_lists(self):
        self.x = []
        self.y = []
        self.z = []

    def append(self, x, y):
        self.x.append(x)
        self.y.append(y)

    def get_x(self):
        return self.x

    def get_y(self):
        return self.y

    def get_z(self):
        return self.x + self.y

    def size(self):
        return len(self.x)

    def dump(self):
        #generate some output

    def do_some_complex_stuff(self, q):
        #lots of calculations and manipulation of the self.x and self.y lists.

    def save_to_db(self):
        #some code that saves x,y lists to the database

    def load_from_db(self, filename):
        #some code that loads x,y lists from the database

私の質問は、このアプローチはDjangoモデルクラスの「汚染」と見なされるのでしょうか、それともこれは大丈夫で個人的な好みの問題なのか、それともモデルクラスがどのように使用されるのかということです。これが推奨されていない、または眉をひそめている場合、クラスの重複に対処するためのより良い方法は何でしょうか?

リストをまとめて削除し、データベースから直接作業するための明白な(?)ソリューションは受け入れられないことに注意してください。これは、より迅速にアクセスするためにメモリ内のリストが必要だからです。たとえば、リストはデータベースからメモリに1回ロードされ、数百回または数千回アクセスされます。各リストは1000を超えるアイテムである可能性があるため、値が必要な場合は、一括読み取り/書き込みは個別アクセスよりもはるかに高速です(多くの場合、順次ではありません)。さらに、多くの場合、データは最終的にデータベースにコミットされる前に数回変更されます。

4

2 に答える 2

1

PythonXYZクラスをDjangoモデルと統合すべきではないようです。Djangoに(個人レコードxyFloatFieldレコードの)データベースを管理させます。コードは、Modelインスタンスのコレクションを実際に管理しているリストロジックを処理します。その個々のModelインスタンスのスコープ外の何かを操作することを目的としたメソッドをModelに持つことは意味がありません。2つの部分からなるソリューション(Collectionクラスを持つManager )が必要になる場合があります。

リストレベルのロード/保存ロジック用のカスタムマネージャーを作成します。これは、リスト操作を操作しているデータベースレコードに概念的に結び付けるため、純粋なジェネリッククラスよりも優れています。Managerは、モデルインスタンスのそれらのx / y / zリストへの初期ロードを処理し、リストをデータベースに保存します。ドキュメントから:

モデルに「テーブルレベル」の機能を追加するには、Managerメソッドを追加することをお勧めします。(「行レベル」の機能(つまり、モデルオブジェクトの単一インスタンスに作用する関数)の場合は、カスタムManagerメソッドではなくModelメソッドを使用します。)

カスタムマネージャーメソッドは、必要なものをすべて返すことができます。QuerySetを返す必要はありません。

リストはそれ自体がエンティティのように聞こえるので、do_some_complex_stuff()、size()、dump()などのメソッドをリストに提供するCollectionクラスが必要になる場合があります。これはPythonXyzあなたが今持っているオブジェクトです。listappend()などの再実装を回避するためにサブクラス化できる場合があります。Manager load()は、save()がコレクションをデータベース書き込み用のModelインスタンスに変換している間に、このCollectionクラスを返す可能性があります。

3つのアプリ間で共通のコードを共有する限り。

  • 抽象モデルを使用して、具体的なアプリモデルで共通のコードを保持できます。
  • スキーマレベルで共通性にアクセスする必要がある場合は、抽象親モデルを使用しないでください。(これにより、ベーステーブルと、アプリ固有の列のみを保持する個々のテーブルが作成されます。)
  • プロキシモデルは、異なる動作が必要で、スキーマが同じ/共有されている場合にのみ使用できます。
于 2012-07-14T21:00:58.160 に答える
0

すべての PythonXyz メソッドを DjangoXyzModel クラスに完全に統合する

しないでください。基本クラスを分離したままにして、MI を使用してそれらを結合するモデル プロキシを作成し、必要に応じて動作をオーバーライドします。

于 2012-07-14T15:27:20.697 に答える