0

Djangoアプリケーションを作成しているときに、ある種のジレンマに直面していますが、私が直面している問題は、MVCパターンに一般的に当てはまると思います。Questionクイズやアンケートの作成に使用できるモデルを作成しています。基本クラスはQuestion、単純な無料回答の質問になります。多肢選択式の質問やスライディングスケールの質問など、さまざまな種類の質問をサポートしたいと思います。これらはQuestion、可能な選択肢の配列などの追加フィールドが追加された基本クラスのサブクラスになります。将来、より多くのタイプの質問をサポートするように質問モデルを拡張できるようにしたいと思います。そのために、ポリモーフィズムに依存して、Questionのすべてのサブクラスのモデルレイヤーとビューレイヤーの間でタイプのオブジェクトを渡すことができますQuestion

私が直面している問題は、ビューをレンダリングするために、ビューが受け取った質問のタイプを認識している必要があることです。多肢選択問題が発生した場合は、ラジオ選択ウィジェットなどを描画する必要があります。したがって、モデルをより多くの種類の質問で拡張する場合は、モデルレイヤーとビューレイヤーの両方に追加する必要があります。Questionオブジェクトを受け取るビューは、受け取った質問のサブクラスタイプを常に知っている必要があるため、これはポリモーフィズムのポイントを打ち負かすようです。質問をモデルに戻す責任を委任することで、この問題を回避できます。Questionモデルにと呼ばれる仮想関数がある場合render_question()そのサブクラスがオーバーライドすると、ビューレイヤーはその関数を呼び出して、質問のタイプを気にせずに適切なHTMLを出力できるようになります。しかし、HTMLレンダリングコードをモデルにバインドするという問題があります。

私が考えた解決策のどちらの欠点も持たない3番目の解決策はありますか?それとも、これは本当に難しい決断を下さなければならないジレンマですか?

4

1 に答える 1

0

モデル/ビューの分離は、プレゼンテーションをデータから切り離すことを目的としています。のポリモーフィックモデル階層の最初の説明は、Question確かに有効なアプローチです。

ここで本当にやりたいことは、Djangoのモデル継承を使用してデータ階層を処理することを検討することです。

BaseQuestion <- FreeQuestion, 
                MultipleChoiceQuestion, 
                SlidingScaleQuestion etc.

次に、同じ原則構造を使用して、を表示する方法(たとえば、質問文字列をレンダリングし、スタイルを設定するなど)BaseQuestionViewを知っているを構築できます。BaseQuestion

BaseQuestionView <- FreeQuestionView, 
                    MultipleChoiceQuestionView, 
                    SlidingScaleQuestionView

BaseQuestionViewを抽象化してBaseQuestion、DBからすべてのモデルインスタンスをプルし、、、、サブクラスのそれぞれに実装されている抽象メソッドを呼び出すことがrender_questionできます。したがって、モデルでの動作を知っており、回答(テキストフィールド)のウィジェットをレンダリングする方法のみを実装します。ラジオボックスなどをレンダリングする方法のみを実装します。FreeQuestionViewMultipleChoiceQuestionViewSlidingScaleQuestionViewFreeQuestionViewFreeQuestionMultipleChoiceQuestionView

言い換えると、レンダリングの実装がモデルクラスではなくビュークラスにあることを除いて、最初のケースで提示したものとほぼ同じです。

同じクラスのオブジェクトを異なる方法でレンダリングする場合は、同じ原則を適用できます。


モデル継承を使用すると、ドット表記を使用してベースインスタンスの任意のサブクラスにアクセスできますquestion.freequestion。これにより、ベースインスタンスに関連付けられたFreeQuestionインスタンスが返されるかQuestion.DoesNotExist、クラスでない場合はレイズされます。

クラスベースのビューを使用すると、天気に応じて質問を異なる方法でレンダリングできるMixinを追加できます。これは、PythonのMROパターンを使用したFreeQuestion、MultipleChoiceQuestion、またはサブクラス化できます。

Djangoが継承されたモデルと継承されたビューの間の相関関係を自動的に作成する方法がないことを私が知っている限り、マッピングを自分で作成する必要があります。

おそらく最も簡単なアプローチは、FreeQuestions、MultipleChoiceQuestionsなどに関連する最初のQuestion QuerySetに一致するすべてのインスタンスを個別に明示的に要求し、それらをリストにキャストしてからメインレンダラーにフィードすることmap[question.__class__]です。混入します。または、クラスマッピングを処理する必要がないように、基本クラスに質問タイプを保持し、DBがこの点で役立つようにすることもできます。

ただし、通常、同じクラスに対してモデルの動作を動的に変更することは望ましくありません(これは、BaseQuestionで効果的に行っていることです)。これは、RESTを念頭に置いて設計する場合に特に当てはまります。これは、明示的なURLを抽象型ではなく、明示的な具象にマップする必要があるためです。

于 2012-07-12T00:25:19.027 に答える