2

多くのブロックが関連付けられているページがあるとします。また、各ブロックには、カスタムのレンダリング、保存、およびデータが必要です。

コードの観点から見ると、これらのモデルごとに異なるクラス (したがってモデル) を定義するのが最も簡単です。次のように簡略化されます。

class Page(models.Model):
    name = models.CharField(max_length=64)

class Block(models.Model):
    page = models.ForeignKey(Page)

    class Meta():
        abstract = True

class BlockType1(Block):

    other_data = models.CharField(max_length=32)

    def render(self):
        """Some "stuff" here """
        pass

class BlockType2(Block):

    other_data2 = models.CharField(max_length=32)

    def render(self):
        """Some "other stuff" here """
        pass

しかしその後、

  • page.block_set.all()このコードでも、ブロックの種類に関係なく、すべての異なるブロックを取得するようなクエリを実行できません。
  • 上記の理由は、各モデルが異なるテーブルを定義するためです。リンク モデルと一般的な外部キーを使用して回避することで問題を解決できますが、それでもページごとに複数のデータベース テーブル クエリが残ります。

それをモデル化する正しい方法は何でしょうか?一般的な外部キー (またはその他のもの) を何らかの方法で使用して、できれば同じデータベース テーブルにデータを格納しながら、継承パラダイムを実現できますか。

アップデート:

私のポイントは、どうすればOOPパラダイムを機能させることができるかということでした非常に多くのifで同じ方法を使用することは、私がやりたかったことではありません。

最良の解決策は、同じモデルをインスタンス化することにより、データとその「タイプ」を保存する保存を定義する別の標準pythonクラス(できれば別のblocks.pyで)を作成することです。次に、テンプレート タグと、モデルのタイプに基づいてレンダリング、保存、およびその他のメソッドを呼び出すフィルターを作成します。

4

2 に答える 2

4

データベースでページをモデル化しないでください。ページはプレゼンテーションです。

まず第一に、データを正しく取得します。

「そして、各ブロックにはカスタムのレンダリング、保存、およびデータが必要です。」これを分解してください。固有のデータがあります。モデルの観点から「ブロック」と「レンダリング」を無視します。プレゼンテーションに関係なく、データを定義するだけです。

真剣に。プレゼンテーションやレンダリングなどを考慮せずに、モデル内のデータを定義するだけです。データモデルを正しく取得します。

モデルとプレゼンテーションを混同すると、何もうまく機能しません。そして、それを機能させたとしても、それを拡張したり再利用したりすることはできません。

2つ目は、データ モデルが正しくなった後でのみ、プレゼンテーションに取りかかることができます。

「ブロック」は、HTML<div>タグとスタイル シートで簡単に行うことができます。まずそれを試してください。結局のところ、モデルは機能し、非常に単純です。これは単なる HTML と CSS であり、モデルとは別のものです。

より複雑な条件付き HTML を作成するには、「ブロック」にカスタム テンプレート タグが必要になる場合があります。その秒を試してみてください。

「ブロック」は、極端な場合には非常に複雑で、いくつかのオブジェクトを HTML に変換する特殊なビュー関数を作成する必要がある場合があります。これは非常にまれです。テンプレートタグでこれを行うことができないと確信するまで、これを行うべきではありません。


編集。

「さまざまな外部データ ソースを照会する」

「保存メソッドを持ち、同じデータベーステーブルに書き込む単純なクラス(モデルではない)を分離します。」

3 つのまったく異なる、関連のない、別々のものがあります。

  • モデル。永続的なモデル。save()メソッドで。これらはほとんど何もしません。属性といくつかのメソッドがあります。「さまざまな外部データ ソースにクエリを実行する」必要はありません。「HTML でのレンダリング」はありません。

  • 外部データ ソース。これらは、データを取得する通常の Python クラスです。これらのオブジェクトは、(1) 外部データを取得し、(2) モデル オブジェクトを作成します。何もありません。「持続性」がない。「HTML でのレンダリング」はありません。

  • プレゼンテーション。これらは、Model オブジェクトを表す通常の Django テンプレートです。外部クエリはありません。持続性なし。

于 2009-12-21T12:33:15.597 に答える
1

スペードでこの問題が発生するシステムのプロトタイプを完成させました。基本のProductクラスと、大きく異なる約200の詳細クラスです。Productに対して一般的なクエリを実行しているが、レンダリング中にサブクラス固有の詳細を処理したいという状況はたくさんあります。たとえば、ベンダーXからすべての製品を取得しますが、特定のサブクラスのグループごとにわずかに異なるテンプレートで表示します。

GenericForeignKeyの非表示フィールドを基本クラスに追加しました。これにより、save()時に子クラスのcontent_type&が自動的に入力されます。object_id汎用のProductオブジェクトがある場合obj = prod.detail、サブクラスオブジェクトを直接操作できます。約20行のコードを取り、それはうまく機能します。

テスト中に遭遇した1つの落とし穴は、manage.py dumpdataその後にmanage.py loaddataスローを続けることIntegrity Errorsでした。これはよく知られた問題であり、1.2リリースで修正される予定です。mysqlコマンドを使用してテストデータセットをダンプ/リロードすることで回避します。

于 2009-12-21T16:33:00.880 に答える