デザイン哲学
このドキュメントでは、Djangoの開発者がフレームワークの作成に使用した基本的な哲学のいくつかについて説明します。 その目標は、過去を説明し、未来を導くことです。
全体
緩い結合
Djangoのスタックの基本的な目標は、緩い結合と緊密な凝集度です。 フレームワークのさまざまな層は、絶対に必要でない限り、お互いを「知る」べきではありません。
たとえば、テンプレートシステムはWebリクエストについて何も知らず、データベースレイヤーはデータ表示について何も知らず、ビューシステムはプログラマーがどのテンプレートシステムを使用するかを気にしません。
Djangoには便宜上フルスタックが付属していますが、スタックの各部分は可能な限り他のスタックから独立しています。
より少ないコード
Djangoアプリは、できるだけ少ないコードを使用する必要があります。 彼らは定型文を欠いているはずです。 Djangoは、イントロスペクションなどのPythonの動的機能を最大限に活用する必要があります。
迅速な開発
21世紀のWebフレームワークのポイントは、Web開発の面倒な側面を高速化することです。 Djangoは、信じられないほど迅速なWeb開発を可能にするはずです。
繰り返さないでください(DRY)
すべての異なる概念および/またはデータは、1つの場所にのみ存在する必要があります。 冗長性が悪いです。 正規化は良いです。
フレームワークは、合理的な範囲内で、可能な限り少ないものから可能な限り多くを推測する必要があります。
明示的は暗黙的よりも優れています
これは、 PEP 20 にリストされているPythonのコア原則であり、Djangoがあまり「魔法」を実行してはならないことを意味します。 本当に正当な理由がない限り、魔法は起こらないはずです。 Magicは、他の方法では達成できない大きな利便性を生み出す場合にのみ使用する価値があり、この機能の使用方法を学ぼうとしている開発者を混乱させるような方法で実装されていません。
一貫性
フレームワークは、すべてのレベルで一貫している必要があります。 一貫性は、低レベル(使用されるPythonコーディングスタイル)から高レベル(Djangoの使用の「経験」)まですべてに適用されます。
モデル
明示的は暗黙的よりも優れています
フィールドは、フィールドの名前だけに基づいて特定の動作を想定するべきではありません。 これにはシステムに関する知識が多すぎて、エラーが発生しやすくなります。 代わりに、動作はキーワード引数に基づいており、場合によってはフィールドのタイプに基づいている必要があります。
関連するすべてのドメインロジックを含める
モデルは、MartinFowlerの Active Record デザインパターンに従って、「オブジェクト」のあらゆる側面をカプセル化する必要があります。
これが、モデルによって表されるデータとその情報(人間が読める名前、デフォルトの順序などのオプションなど)の両方がモデルクラスで定義されている理由です。 特定のモデルを理解するために必要なすべての情報は、モデルに ' で保存する必要があります。
データベースAPI
データベースAPIの主要な目標は次のとおりです。
SQLの効率
SQLステートメントの実行回数をできるだけ少なくし、ステートメントを内部的に最適化する必要があります。
これが、開発者が舞台裏で物事を黙って保存するのではなく、save()
を明示的に呼び出す必要がある理由です。
これが、select_related()
QuerySet
メソッドが存在する理由でもあります。 これは、「関連するすべてのオブジェクト」を選択する一般的なケースのオプションのパフォーマンスブースターです。
簡潔で強力な構文
データベースAPIは、可能な限り少ない構文で豊富で表現力豊かなステートメントを許可する必要があります。 他のモジュールやヘルパーオブジェクトのインポートに依存しないでください。
結合は、必要に応じて、バックグラウンドで自動的に実行する必要があります。
すべてのオブジェクトは、システム全体ですべての関連オブジェクトにアクセスできる必要があります。 このアクセスは両方の方法で機能するはずです。
必要に応じて生のSQLに簡単にドロップするオプション
データベースAPIは、それがショートカットであることを認識している必要がありますが、必ずしもすべてを網羅しているとは限りません。 フレームワークは、カスタムSQL(ステートメント全体、またはAPI呼び出しのカスタムパラメーターとしてカスタムWHERE
句のみ)を簡単に記述できるようにする必要があります。
URLデザイン
緩い結合
DjangoアプリのURLは、基盤となるPythonコードに結合しないでください。 URLをPython関数名に結び付けることは、悪いことであり、醜いことです。
これらの方針に沿って、Django URLシステムは、同じアプリのURLが異なるコンテキストで異なることを許可する必要があります。 たとえば、あるサイトが/stories/
にストーリーを配置し、別のサイトが/news/
を使用する場合があります。
無限の柔軟性
URLは可能な限り柔軟にする必要があります。 考えられるすべてのURLデザインを許可する必要があります。
ベストプラクティスを奨励する
フレームワークは、開発者が醜いURLよりもきれいなURLを設計するのと同じくらい簡単(またはさらに簡単)にする必要があります。
WebページのURLのファイル拡張子は避ける必要があります。
URLのビネットスタイルのコンマは厳しい罰に値します。
決定的なURL
技術的には、foo.com/bar
とfoo.com/bar/
は2つの異なるURLであり、検索エンジンロボット(および一部のWebトラフィック分析ツール)はそれらを別々のページとして扱います。 Djangoは、検索エンジンロボットが混乱しないように、URLを「正規化」するように努力する必要があります。
これが:setting: `APPEND_SLASH` 設定の背後にある理由です。
テンプレートシステム
ロジックをプレゼンテーションから分離する
テンプレートシステムは、プレゼンテーションとプレゼンテーション関連のロジックを制御するツールと見なされています。それだけです。 テンプレートシステムは、この基本的な目標を超える機能をサポートするべきではありません。
冗長性を排除する
動的なWebサイトの大部分は、共通のヘッダー、フッター、ナビゲーションバーなど、ある種の共通のサイト全体のデザインを使用しています。 Djangoテンプレートシステムは、これらの要素を1つの場所に簡単に保存できるようにし、重複するコードを排除する必要があります。
これがテンプレート継承の背後にある哲学です。
HTMLから切り離されます
テンプレートシステムは、HTMLのみを出力するように設計するべきではありません。 他のテキストベースのフォーマット、または単なるプレーンテキストの生成にも同様に優れているはずです。
テンプレート言語にはXMLを使用しないでください
XMLエンジンを使用してテンプレートを解析すると、テンプレートの編集にまったく新しいヒューマンエラーが発生し、テンプレート処理で許容できないレベルのオーバーヘッドが発生します。
デザイナーの能力を前提とする
テンプレートシステムは、DreamweaverなどのWYSIWYGエディターでテンプレートが必ずしも適切に表示されるように設計するべきではありません。 これは制限が厳しすぎるため、構文をそれほど適切に保つことはできません。 Djangoは、テンプレートの作成者がHTMLを直接編集することに慣れていることを期待しています。
空白を明らかに扱う
テンプレートシステムは、空白を使って魔法のようなことをするべきではありません。 テンプレートに空白が含まれている場合、システムは空白をテキストと同じように扱う必要があります。表示するだけです。 テンプレートタグにない空白はすべて表示する必要があります。
プログラミング言語を発明しないでください
目標はプログラミング言語を発明することではありません。 目標は、プレゼンテーション関連の意思決定に不可欠な、分岐やループなどのプログラミング風の機能を十分に提供することです。 Djangoテンプレート言語(DTL)は、高度なロジックを回避することを目的としています。
Djangoテンプレートシステムは、テンプレートがプログラマーではなくデザイナーによって作成されることが最も多いことを認識しているため、Pythonの知識を前提とすべきではありません。
安全性と保安
テンプレートシステムは、すぐに使用できるように、データベースレコードを削除するコマンドなどの悪意のあるコードを含めることを禁止する必要があります。
これは、テンプレートシステムが任意のPythonコードを許可しないもう1つの理由です。
拡張性
テンプレートシステムは、高度なテンプレート作成者がそのテクノロジを拡張したい場合があることを認識する必要があります。
これは、カスタムテンプレートタグとフィルターの背後にある哲学です。
ビュー
シンプルさ
ビューの記述は、Python関数の記述と同じくらい簡単である必要があります。 開発者は、関数が実行するときにクラスをインスタンス化する必要はありません。
リクエストオブジェクトを使用する
ビューは、リクエストオブジェクト(現在のリクエストに関するメタデータを格納するオブジェクト)にアクセスできる必要があります。 オブジェクトは、ビュー関数がグローバル変数から要求データにアクセスする必要があるのではなく、ビュー関数に直接渡される必要があります。 これにより、「偽の」リクエストオブジェクトを渡すことで、ビューを軽く、クリーンに、簡単にテストできます。
緩い結合
ビューは、開発者がどのテンプレートシステムを使用するか、あるいはテンプレートシステムがまったく使用されているかどうかさえ気にする必要はありません。
GETとPOSTを区別する
GETとPOSTは異なります。 開発者は、どちらか一方を明示的に使用する必要があります。 フレームワークは、GETデータとPOSTデータを簡単に区別できるようにする必要があります。
キャッシュフレームワーク
Djangoのキャッシュフレームワークの主な目標は次のとおりです。
より少ないコード
キャッシュは可能な限り高速である必要があります。 したがって、特にget()
操作の場合、キャッシュバックエンドを取り巻くすべてのフレームワークコードを最小限に抑える必要があります。
一貫性
キャッシュAPIは、さまざまなキャッシュバックエンド間で一貫したインターフェイスを提供する必要があります。