=================== Django の設計思想 =================== :revision-up-to: 17812 (1.4) このドキュメントでは、 Django の開発者たちがフレームワークの構築に取り入れ ている根本的な設計思想についていくつか解説します。それによって、 Django の これまでの経緯に説明を与えつつ、将来への指針にしたいと思います。 全体的な設計思想 ================ .. _loose-coupling: ルースカップリング ------------------ .. index:: coupling; loose Django のスタックが目指す基本的なゴールは `ルースカップリングとタイトコヒージョン`_ の実現にあります。 フレームワークの様々なレイヤは、本当に必要な場合を除き、お互いの事情を 知らなくてもよいという考え方です。 例えば、テンプレートシステムは Web リクエストがどのようなものか関知せず、 データベースレイヤはデータをどう表示するかに関知せず、ビューシステムはプロ グラマがどんなテンプレートシステムを使うかに関知しません。 利便性のため、 Django には全てのスタックがついてきますが、スタックの各部分 は可能な限り互いに独立しています。 .. _`ルースカップリングとタイトコヒージョン`: http://c2.com/cgi/wiki?CouplingAndCohesion .. _`loose coupling and tight cohesion`: http://c2.com/cgi/wiki?CouplingAndCohesion .. _less-code: コード量の低減 -------------- Django アプリケーションのコードは可能なかぎり少なくし、冗長な決まり文句を排 除します。 Django では、イントロスペクションのような Python の動的な決定機 能を積極的に活用します。 .. _quick-development: 迅速な開発 ---------- 21 世紀の Web フレームワークのポイントは、Web 開発の単調でのろくさい部分を 高速化することにあります。 Django は Web 開発を信じられないくらいに迅速化し ます。 .. _dry: DRY (Don't repeat yourself) 則 ------------------------------- .. index:: single: DRY single: Don't repeat yourself 個別のコンセプトやデータは、一つの、ただ一つの場所に置かねばなりません。冗 長は悪、正規化は善です。 こうした理由から、フレームワークは可能な限り小さくせねばなりません。 .. seealso:: `Portland Pattern Repository の DRY に関する議論`__ __ http://c2.com/cgi/wiki?DontRepeatYourself .. _explicit-is-better-than-implicit: 暗示的より明示的に ------------------ この思想は :pep:`20` にも挙げられている Python のコア思想で、 Django はで きるだけ「黒魔術」を避けるべきという意味です。どうしても必要な理由がない かぎり魔術的な処理を取り入れません。魔術的な処理を取り入れる価値があるの は、他の方法では実現し得ない多大な利便性が生まれ、かつその機能の使い方を 学ぼうとする開発者が混乱しないような形で実装できる場合だけです。 .. _consistency: 一貫性 ------ フレームワークは全ての水準で一貫性を保たねばなりません。この一貫性は低水準 (Python のコーディングスタイル) から高水準 (Djangoの「使用感:experience」) にいたる全てにあてはまります。 モデル ====== 暗示的より明示的に ------------------ データの挙動をフィールド名だけから決定してはなりません。さもなければ必要以 上にシステムを熟知せねばならず、エラーのもとになります。 その代り、データの挙動はキーワード引数や、場合によってはフィールドのタイプ に基づいて決定します。 関連領域のロジックは全てまとめる -------------------------------- モデルは「オブジェクト」としての様々な側面をカプセル化し、いわゆる Martin Fowler の `アクティブレコード`_ デザインパターンに従わねばなりません。 そのため、モデルの表現するデータや、モデル自身の情報 (人間可読な名前、デフォ ルトの整列順など) は、モデルクラスで定義されています。あるモデルを理解する のに必要な情報は、全てモデルの *中に* 入っているのです。 .. _`アクティブレコード`: http://www.martinfowler.com/eaaCatalog/activeRecord.html .. _`Active Record`: http://www.martinfowler.com/eaaCatalog/activeRecord.html データベース API ================ データベース API の主要な目的を示します: SQL を効率化する ---------------- SQL 文の実行は可能な限り少なくし、内部的に最適化せねばなりません。 データの保存をフレームワークに背後で暗黙のうちに行わせず、開発者に ``save()`` を明示的に呼び出させるのはこのためです。 また、 ``QuerySet`` の ``select_related()`` メソッドが存在するのもこのため です。 ``select_related`` は「関連する全てのオブジェクト」を select すると いう、よくあるケースに対してパフォーマンス向上をもたらします。 むだのない強力な構文 ---------------------- データベース API は、高機能かつ表現性に富み、可能な限り小さな構文でなければ なりません。 API は他のモジュールやヘルパオブジェクトに依存してはなりません。 join は必要に応じて舞台裏で自動的に行われねばなりません。 システム全体にわたって、各オブジェクトは自分とリレーションにあるオブジェク トにアクセスできねばなりません。リレーションの追跡は双方向に行われねばなり ません。 必要なら生の SQL も簡単に使えるようにする ------------------------------------------- データベース API の設計では、ショートカットとして便利でありながらも、必ずし も全ての機能に手がとどかなくてもよいということを理解していなければなりませ ん。フレームワークは SQL 文全体、あるいは ``WHERE`` 節だけのカスタムの SQL を簡単に書けるようにせねばなりません。 URL の設計 ========== ルースカップリング ------------------ Django アプリケーションでは、 URL を特定の Python コードとカップリングして はなりません。 URL と Python 関数名の関連づけは、間違っており、美しくありま せん。 同様に、 Django の URL システムは同じアプリケーションを異なるコンテキストで 使えねばなりません。例えば、あるサイトで記事 (story) にアクセスするのに ``/stories/`` を使っていたとしても、別のところで ``/news/`` という URL で記 事にアクセスできねばなりません。 無限の柔軟性 ------------ URL には可能な限り柔軟性をもたせねばなりません。考えられるいかなる URL 設計 も使えねばなりません。 王道を進みやすく ---------------- フレームワークはすっきりとした URL 設計を (汚い設計よりも) 簡単におこなえね ばなりません。 Web ページの URL にファイル拡張子を使うのは避けねばなりません。 URL にカンマを入れる Vignette スタイルは厳しく禁じねばなりません。 .. _definitive-urls: URL ははっきりと ---------------- .. index:: urls; definitive 技術的には、 ``foo.com/bar`` と ``foo.com/bar/`` は別個の URL であり、検索 エンジンロボット (や Web トラフィック解析ツール) はこれらのページを別々のも のとして扱わねばなりません。 Django は URL を「正規化」して、検索エンジンロ ボットを混乱させないようにせねばなりません。 これは :setting:`APPEND_SLASH` 設定の根底にある考えです。 テンプレートシステム ==================== .. _separation-of-logic-and-presentation: プレゼンテーションとロジックの分離 ---------------------------------- 私達は、テンプレートシステムはプレゼンテーションとプレゼンテーション関係の ロジックを制御するためのツールであり、それ以上のものではないと考えています。 その本分をこえた機能をテンプレートシステムに求めるべきではありません。 何もかもテンプレートに押し込みたかったのなら、今ごろ PHP を使っていたでしょ う。かつてそうしていましたが、今はやめ、そこから学んだのです。 冗長さを防ぐ ------------ 大多数の動的な Web サイトでは、ヘッダやフッタ、ナビゲーションバーといった部 分のデザインをサイト全体で共通にしています。 Django テンプレートシステムは、 こうしたサイトの構成要素を一箇所に保存しやすくし、コードの複製を無くさねば なりません。 これは :ref:`テンプレートの継承` の根底にある考え方で す。 HTML に縛られない ----------------- HTML だけを出力するようにテンプレートシステムを設計すべきではありません。 他のテキストベース形式や単なる平文テキストの生成もうまく実現できねばなりま せん。 XML をテンプレート言語に使わない -------------------------------- .. index:: xml; suckiness of テンプレートのパージングに XML エンジンを使うと、テンプレート編集における 人為エラーという新たな問題に直面します。それに、テンプレート処理に受け入れ がたいオーバヘッドを被ることになります。 ページデザイナの有能さを前提にする ---------------------------------- 必ずしも Dreamweaver のような WYSIWYG エディタでうまく表示できるように テンプレートシステムを設計する必要はありません。そのような要求は制限が 厳しすぎ、本来あるべきすっきりした構文を実現できなくなります。 Django では 直接 HTML を編集する作業に慣れたテンプレート作者を想定しています。 空白の扱いはわかりやすく ------------------------ テンプレートシステムは魔法的な空白の処理を行ってはなりません。テンプレート に空白をいれた場合、システムは空白部分を普通のテキストと同じように扱う、 すなわちそのまま表示せねばなりません。逆に、テンプレートタグにない空白を 表示すべきでもありません。 プログラミング言語を作り直さない -------------------------------- テンプレートシステムでは、以下の機能を意図的に使えないようにしています: * 変数の代入 * 高度なロジック テンプレートシステムが目的とするのは新たなプログラミング言語の発明では ありません。目的は、分岐やループといった、プレゼンテーションまわりの判定で 必須のプログラム機能の提供だけです。 Django テンプレートシステムでは、最もテンプレートを良く書くのは *プログラマ* ではなく *デザイナ* とみなしており、 Python の知識を前提には していません。 安全性とセキュリティ -------------------- テンプレートシステムは、使い始めの時点で、外部コマンドの実行やデータベース レコードの削除といった悪意あるコードを取り込めないようになっていなければなり ません。 これは、テンプレートシステムが任意の Python コードにアクセスできるように してはならないもう一つの理由でもあります。 拡張性 ------ テンプレートシステムは、高度なテンプレート作者によるテクノロジの拡張に配慮 せねばなりません。 これはカスタムテンプレートタグやフィルタの根底にある哲学です。 ビュー ====== 簡潔性 ------ ビューは Python の関数として可能な限りシンプルに書きます。開発者は関数でで きることを実現するために、クラスのインスタンスを生成する必要はありません。 リクエストオブジェクトの利用 ----------------------------- ビューはリクエストオブジェクトにアクセスします。リクエストオブジェクトとは、 現在のリクエストに関するメタデータを入れるオブジェクトです。ビューはこのオ ブジェクトをグローバル変数経由でアクセスするのではなく、引数として直接受け 取るようにすべきです。それにより、「偽の」リクエストオブジェクトを渡してビュー を簡単かつクリーンにテストできるようになります。 ルースカップリング ------------------ ビューは開発者がどのテンプレートシステムを使うか関知すべきではなく、使って いるテンプレートシステムがいくつかすら関知すべきではありません。 GET と POST の使い分け ---------------------- GET と POST は全く違います。開発者はこれらを明示的に使い分けねばなりません。 フレームワークはデータの GET と POST を容易に判別できねばなりません。