From f8ca662ad1378434939872681e9b1986e8b10c26 Mon Sep 17 00:00:00 2001 From: whosaysni Date: Sat, 24 Mar 2007 13:33:12 +0000 Subject: [PATCH 1/4] added link to 0.96 --- add_ons.txt | 237 ++++ admin_css.txt | 201 +++ apache_auth.txt | 81 ++ api_stability.txt | 155 +++ authentication.txt | 1149 ++++++++++++++++++ cache.txt | 612 ++++++++++ contributing.txt | 737 +++++++++++ csrf.txt | 82 ++ databases.txt | 193 +++ db-api.txt | 1936 +++++++++++++++++++++++++++++ design_philosophies.txt | 362 ++++++ distributions.txt | 89 ++ django-admin.txt | 578 +++++++++ documentation.txt | 159 +++ email.txt | 208 ++++ faq.txt | 827 +++++++++++++ fastcgi.txt | 355 ++++++ flatpages.txt | 137 +++ forms.txt | 743 ++++++++++++ generic_views.txt | 1166 ++++++++++++++++++ i18n.txt | 827 +++++++++++++ index.txt | 155 +++ install.txt | 156 +++ legacy_databases.txt | 101 ++ middleware.txt | 257 ++++ model-api.txt | 2086 ++++++++++++++++++++++++++++++++ modpython.txt | 254 ++++ multiple_database_support.txt | 175 +++ newforms.txt | 941 ++++++++++++++ outputting_csv.txt | 133 ++ outputting_pdf.txt | 171 +++ overview.txt | 331 +++++ redirects.txt | 93 ++ release_notes_0.95.txt | 135 +++ release_notes_0.96.txt | 282 +++++ request_response.txt | 595 +++++++++ serialization.txt | 137 +++ sessions.txt | 365 ++++++ settings.txt | 1159 ++++++++++++++++++ sitemaps.txt | 377 ++++++ sites.txt | 354 ++++++ static_files.txt | 149 +++ syndication_feeds.txt | 815 +++++++++++++ templates.txt | 1344 ++++++++++++++++++++ templates_python.txt | 1300 ++++++++++++++++++++ testing.txt | 619 ++++++++++ transactions.txt | 178 +++ tutorial01.txt | 635 ++++++++++ tutorial02.txt | 501 ++++++++ tutorial03.txt | 522 ++++++++ tutorial04.txt | 293 +++++ url_dispatch.txt | 533 ++++++++ writing-apps-guide-outline.txt | 0 53 files changed, 25980 insertions(+) create mode 100644 add_ons.txt create mode 100644 admin_css.txt create mode 100644 apache_auth.txt create mode 100644 api_stability.txt create mode 100644 authentication.txt create mode 100644 cache.txt create mode 100644 contributing.txt create mode 100644 csrf.txt create mode 100644 databases.txt create mode 100644 db-api.txt create mode 100644 design_philosophies.txt create mode 100644 distributions.txt create mode 100644 django-admin.txt create mode 100644 documentation.txt create mode 100644 email.txt create mode 100644 faq.txt create mode 100644 fastcgi.txt create mode 100644 flatpages.txt create mode 100644 forms.txt create mode 100644 generic_views.txt create mode 100644 i18n.txt create mode 100644 index.txt create mode 100644 install.txt create mode 100644 legacy_databases.txt create mode 100644 middleware.txt create mode 100644 model-api.txt create mode 100644 modpython.txt create mode 100644 multiple_database_support.txt create mode 100644 newforms.txt create mode 100644 outputting_csv.txt create mode 100644 outputting_pdf.txt create mode 100644 overview.txt create mode 100644 redirects.txt create mode 100644 release_notes_0.95.txt create mode 100644 release_notes_0.96.txt create mode 100644 request_response.txt create mode 100644 serialization.txt create mode 100644 sessions.txt create mode 100644 settings.txt create mode 100644 sitemaps.txt create mode 100644 sites.txt create mode 100644 static_files.txt create mode 100644 syndication_feeds.txt create mode 100644 templates.txt create mode 100644 templates_python.txt create mode 100644 testing.txt create mode 100644 transactions.txt create mode 100644 tutorial01.txt create mode 100644 tutorial02.txt create mode 100644 tutorial03.txt create mode 100644 tutorial04.txt create mode 100644 url_dispatch.txt create mode 100644 writing-apps-guide-outline.txt diff --git a/add_ons.txt b/add_ons.txt new file mode 100644 index 0000000..e474ec8 --- /dev/null +++ b/add_ons.txt @@ -0,0 +1,237 @@ +============================= +"django.contrib" 下のアドオン +============================= + +:revision-up-to: 4805 (release 0.96) + +Django は Python の `"batteries included" 哲学`_ を目指しています. Django +には Web 開発における課題を解くための様々な外部オプションツールがついてきま +す. + +これらのコードは Django 配布物中の ``django/contrib`` にあります. +``contrib`` 下のパッケージの概要を以下に示します: + +.. _`"batteries included" 哲学`: http://python.jp/doc/release/tut/node12.html#batteries-included + +admin +===== + +Django の自動化管理インタフェースです.詳しくは `チュートリアルその 2`_ を +参照してください. + +.. _`チュートリアルその 2`: ../tutorial02/ +.. _Tutorial 2: ../tutorial2/ + +auth +==== + +Django の認証フレームワークです.詳しくは `認証のドキュメント`_ を参照して +下さい. + +.. _`認証のドキュメント`: ../authentication/ + +comments +======== + +単純かつ柔軟なコメントシステムです.まだドキュメントはありません. + +contenttypes +============ + +コンテンツの「タイプ」をフックするための軽量フレームワークです.インストー +ルした Django モデルはそれぞれ固有のコンテンツタイプになります.まだドキュ +メントはありません. + +csrf +==== + +クロスサイトリクエストフォージェリ (Cross Site Request Forgeries) を阻止す +るためのミドルウェアです. + +`csrf のドキュメント`_ を参照してください. + +.. _`csrf のドキュメント`: ../csrf/ +.. _csrf documentation: ../csrf/ + +formtools +========= + +Django の新しいフォーム (django.newforms) に対する高水準の抽象化インタフェー +スです. + +django.contrib.formtools.preview +-------------------------------- + +「 HTML フォームを表示し,必ずプレビューを行ってからフォームデータを提出す +る」というワークフローを抽象化したものです. + +この機能に関するドキュメントはまだありませんが, +``django/contrib/formtools/preview.py`` のコードや docstring を手引きすると +よいでしょう. + +humanize +======== + +データに「人間くささ (human touch)」を与えるための Django テンプレートフィ +ルタです。これらのフィルタを有効にするには、 ``INSTALLED_APPS`` 設定に +``'django.contrib.humanize'`` を加えます。インストール後、テンプレート上で +``{% load humanize %}`` を呼び出せば、以下のフィルタを利用できるようになり +ます: + +apnumber +-------- + +1-9 の数字に対して、数をアルファベットで表します。それ以外の数はそのまま数 +字で返します。これは Associated Press の書式に従っています。 + +例: + + * ``1`` は ``'one'`` になります + * ``2`` は ``'two'`` になります。 + * ``10`` は ``10`` になります。 + +渡す値は整数でも、整数を文字列で表したものでもかまいません。 + +intcomma +-------- + +整数を三桁ごとにカンマで区切った形式の文字列に変換します。 + +例: + + * ``4500`` は ``'4,500'`` になります。 + * ``45000`` は ``'45,000'`` になります。 + * ``450000`` は ``'450,000'`` になります。 + * ``4500000`` は ``'4,500,000'`` になります。 + +渡す値は整数でも、整数を文字列で表したものでもかまいません。 + +intword +------- + +大きな整数を読みやすいテキスト表現に変換します。100 万を超えるような値を扱 +う場合に便利です。 + +例: + + * ``1000000`` は ``'1.0 million'`` になります。 + * ``1200000`` は ``'1.2 million'`` になります。 + * ``1200000000`` は ``'1.2 billion'`` になります。 + +Values up to 1000000000000000 (one quadrillion) are supported. + +渡す値は整数でも、整数を文字列で表したものでもかまいません。 + +ordinal +------- + +整数を序数形式の文字列に変換します。 + +例: + + * ``1`` は ``'1st'`` になります。 + * ``2`` は ``'2nd'`` になります。 + * ``3`` は ``'3rd'`` になります。 + +渡す値は整数でも、整数を文字列で表したものでもかまいません。 + + +flatpages +========= + +「フラット (flat) な」 HTML コンテンツをデータベースで扱うためのフレームワー +クです. + +`flatpages のドキュメント`_ を参照してください. + +.. _`flatpages のドキュメント`: ../flatpages/ +.. _flatpages documentation: ../flatpages/ + +localflavor +=========== + +特定の国や文化でのみ有用な Django の短いコード (snippet) を集めたものです. +例えば, ``django.contrib.localflavor.usa.forms`` には,米国の郵便番号 +(U.S. zip code) を検証するための ``USZipCodeField`` が入っています. + + +markup +====== + +テンプレートフィルタの集まりです.以下の 3 つのマークアップ言語に対するフィ +ルタを実装しています: + + * `Textile`_ + * `Markdown`_ + * `ReST (ReStructured Text)`_ + +詳しくは、 django/contrib/markup/templatetags/markup.py のソースコードを参 +照してください。 + +.. _Textile: http://en.wikipedia.org/wiki/Textile_%28markup_language%29 +.. _Markdown: http://en.wikipedia.org/wiki/Markdown +.. _ReST (ReStructured Text): http://en.wikipedia.org/wiki/ReStructuredText + +redirects +========= + +リダイレクトを管理するためのフレームワークです. + +`redirects のドキュメント`_ を参照してください. + +.. _`redirects のドキュメント`: ../redirects/ +.. _redirects documentation: ../redirects/ + + +sessions +======== + +セッション管理のためのフレームワークです. + +`セッションのドキュメント`_ を参照してください. + +.. _`セッションのドキュメント`: ../sessions/ + +sites +===== + +一つのデータベースと Django を使って複数のウェブサイトを操作できるようにす +るための軽量フレームワークです.このフレームワークを使うと,オブジェクトを +特定の (一つまたは複数の) サイトに関連づけできます. + +`sites のドキュメント`_ を参照してください. + +.. _`sites のドキュメント`: ../sites/ +.. _sites documentation: ../sites/ + +sitemaps +======== + +Google サイトマップ XML ファイルを生成するためのフレームワークです. + +`sitemaps のドキュメント`_ を参照してください. + +.. _sitemaps documentation: ../sitemaps/ +.. _`sitemaps のドキュメント`: ../sitemaps/ + + +syndication +=========== + +RSS および Atom 形式の配信フィード (syndication feed) をごく簡単に生成する +ためのフレームワークです. + +`配信フィードフレームワークのドキュメント`_ を参照してください. + +.. _`配信フィードフレームワークのドキュメント`: ../syndication_feeds/ +.. _syndication documentation: ../syndication/ + + + +その他のアドオン +================= + +``contrib`` に入れたらよいと思う機能について何かアイデアがあるなら,是非教 +えて下さい! コードを書いて, `django-users mailing list`_ に送って下さい. + +.. _django-users mailing list: http://groups.google.com/group/django-users diff --git a/admin_css.txt b/admin_css.txt new file mode 100644 index 0000000..bb53e61 --- /dev/null +++ b/admin_css.txt @@ -0,0 +1,201 @@ +======================================= +Django 管理インタフェースのカスタマイズ +======================================= + +:revision-up-to: 4805 (release 0.96) + +Django が動的に生成する admin インタフェースは,コードを書かずに使える完全 +な機能を備えた admin を提供しています. admin は動的管理サイト構築の単なる +足掛かりではなく,実運用の環境でそのまま使えるだけの機能を備えています. +admin ページの根底にある形式は Django で構築されていますが, admin のスタイ +ルシートや画像を編集すればルック & フィールをカスタマイズできます. + +このドキュメントでは, Django の admin の CSS で使われている主要なスタイル +とクラスについてざっと紹介します. + +.. _Modules: + +モジュール +========== + +admin 上ではコンテンツをグループ化する基本の構成要素として ``.module`` クラ +スを使っています. ``.module`` は ``div`` や ``fieldset`` に適用されます. +``.module`` はコンテンツのグループをボックス内にラップし.その中身に一定の +スタイルを適用します.例えば, ``div.module`` 内の ``h2`` タグは,グループ +全体のヘッダになるよう, ``div`` の上に配置されます. + +.. image:: http://media.djangoproject.com/img/doc/admincss/module.gif + :alt: Example use of module class on admin homepage + +.. _Column Types: + +カラムタイプ +============ + +.. class:: note +.. admonition:: Note + + 管理ページは (ダッシュボード部分を除いて) 全て可変幅 (fluid-width) になっ + ており,以前の Django にあった固定幅のクラスは全て除去されています. + +admin ページのベーステンプレートには,ページのカラム構造を決めるブロックが +あります.このブロックにはページのコンテンツ領域 (``div#content``) のクラス +を定義し,コンテンツ領域の幅がわかるようにします.指定できるカラムタイプは +3 種類あります. + +colM + 全てのページのデフォルトのカラムの設定です. "M" は "main" を表します. + 全てのコンテンツは一つのメインカラム (``div#content-main``) に入るもの + と仮定しています. +colMS + 一つのメインカラムと,その右側にサイドバーを持つようなページのカラム設 + 定です. "S" は "sidebar" を表します.メインのコンテンツは + ``div#content-main`` に入り,サイドバーのコンテンツは + ``div#content-related`` に入るものと仮定しています.メインの admin ペー + ジで使われています. +colSM + 上と同じですが,サイドバーは左側に出ます.ソース中でどちらのカラムが先 + にでてくるかは関係ありません. + +例えば,以下のようなコードをテンプレートに張り付ければ,右側のサイドバーを +2 カラムのページにできるでしょう:: + + {% block coltype %}colMS{% endblock %} + + +.. _Text Styles: + +テキストのスタイル +================== + +.. _Font Sizes: + +フォントサイズ +-------------- + +スタイルシートには,ほとんどの HTML 要素 (ヘッダ,リストなど) に対して +コンテキストに応じてベースフォントサイズを指定しています.テキストを +特定のサイズに強制する 3 つのクラスがあります. + +small + 11px +tiny + 10px +mini + 9px (控え目に使ってください) + +.. _Font Styles and Alignment: + +フォントスタイルと字揃え +------------------------ + +テキストのスタイルもいくつかあります. + +.quiet + フォント色をライトグレーにします.説明文の傍注意などに便利です.協調の + 度合を変えるには ``.small`` や ``.tiny`` と組み合わせて下さい. +.help + フォーム要素の機能を説明するインラインヘルプテキストのブロック用に作ら + れたクラスです.テキストを小さいグレーで表示し, ``.form-row`` 要素 + (後述の「フォームのスタイル」参照) 内の ``p`` エレメントで使うと,フォー + ムフィールドと並ぶようにオフセットを決めます.ヘルプテキストには + ``small quiet`` ではなくこのクラスを使ってください.他のエレメントで + も使えますが,できるだけ ``p`` に使うようにしてください. +.align-left + テキストを左揃えにします.インラインエレメントの入ったブロックエレメン + トでしか使えません. +.align-right + テキストを右揃えにします.インラインエレメントの入ったブロックエレメン + トでしか使えません. +.nowrap + テキストとインラインオブジェクトがラップされないようにします. + テーブルヘッダなどを一行に収めたい場合に便利です. + +.. _Floats and Clears: + +float 指定とクリア +------------------ + +float-left + 左よせの float です. +float-right + 右よせの float です. +clear + float 指定を全てクリアします. + +.. _Object Tools: + +オブジェクトツール +================== + +フォームやチェンジリストのページには,オブジェクトに直接適用される操作への +リンクがあります.これらのリンクはチェンジリストの上にある「ツールバー」行 +の右側に表示されます. ツールは ``object-tools`` クラスの ``ul`` でラップ +されています.ツールには二つのカスタムのタイプがあり,ツール内で ``a`` タグ +に指定して使うようになっています. ``.addlink`` と ``.viewsitelink`` です. + + +チェンジリストページではこのようになります:: + + + +.. image:: http://media.djangoproject.com/img/doc/admincss/objecttools_01.gif + :alt: Object tools on a changelist page + +フォームページでは以下のようになっています:: + + + +.. image:: http://media.djangoproject.com/img/doc/admincss/objecttools_02.gif + :alt: Object tools on a form page + +.. _Form Styles: + +フォームのスタイル +================== + +.. _Fieldsets: + +フィールドセット +---------------- + +admin のフォームは ``fieldset`` エレメントでグループごとに分けられています. +各フィールドセットには ``.module`` クラスがなくてはなりません.また, +各フィールドセットの先頭には ``h2`` タグによるヘッダがなくてはなりません +(ただし,フォームの最初のグループや,フィールドグループに論理的なラベル +を必要としない場合は除きます). + +また,各フィールドセットに ``.module`` 以外の追加のクラスを指定して,フィー +ルドグループ全体が適当なフォーマットになるようにしてもかまいません. + +.aligned + ラベルと input エレメントを同じ行に横並びに配置します. +.wide + ``.aligned`` と組み合わせて,ラベルの使えるスペースを広くします. + +.. _Form Rows: + +フォーム行 +---------- + +(``fieldset`` 内の) フォームの各行は ``form-row`` クラスの ``div`` で囲わね +ばなりません.行内に収めるフィールドが必須のフィールドの場合, +``div.form-row`` には ``required`` クラスを追加せねばなりません. + +.. image:: http://media.djangoproject.com/img/doc/admincss/formrow.gif + :alt: Example use of form-row class + +.. _Labels: + +ラベル +------ + +チェックボックスとラジオボタンを除き,フォームのラベルは常にフィールドの前 +にきます.チェックボックスやラジオボックスの場合には ``input`` タグが先にき +ます. ``label`` タグ以降の説明文やヘルプテキストは, ``.help`` クラスの +``p`` タグに入ります. diff --git a/apache_auth.txt b/apache_auth.txt new file mode 100644 index 0000000..f61f957 --- /dev/null +++ b/apache_auth.txt @@ -0,0 +1,81 @@ +=================================================== +Apache での認証に Django のユーザデータベースを使う +=================================================== + +:revision-up-to: 4805 (release 0.96) + +Apache を使っていると,同期を保ちながら複数の認証データベースを維持するとい +う問題によくぶつかります.そこで, Django の `認証システム`_ に対して直接 +Apache から認証をかけるよう設定できます.例えば以下のような処理を実現できま +す: + + * 認証ユーザだけを対象に,静的ファイル/メディアファイルを Apache から + 直接提供できます. + + * 特定のパーミッションを持つ Django ユーザだけに Subversion_ リポジト + リへのアクセスを許すよう認証をかけられます. + + * mod_dav_ で作成した WebDAV 共有への接続を特定ユーザに許可できます. + +.. _Configuring Apache: + +Apache の設定 +============= + +Django の認証データベースを Apache 設定ファイルからチェックするには +mod_python の標準の ``Auth*`` および ``Require`` ディレクティブと共に, +``PythonAuthenHandler`` ディレクティブを使います:: + + + AuthType basic + AuthName "example.com" + Require valid-user + + SetEnv DJANGO_SETTINGS_MODULE mysite.settings + PythonAuthenHandler django.contrib.auth.handlers.modpython + + +デフォルトでは,認証ハンドラは staff のマークのついたメンバだけに +``/example/`` へのアクセスを制限します.この挙動を変更したければ, +以下の ``PythonOption`` ディレクティブを使います: + + ================================ ========================================= + ``PythonOption`` 説明 + ================================ ========================================= + ``DjangoRequireStaffStatus`` ``on`` に設定すると, "staff" ユーザ + (``is_staff`` フラグの立っているユーザ) + だけにアクセスを許可します. + + デフォルトは ``on`` です. + + ``DjangoRequireSuperuserStatus`` ``on`` に設定すると,スーパユーザ + (``is_superuser`` フラグの立っている + ユーザ) だけにアクセスを許可します. + + デフォルトは ``off`` です. + + ``DjangoPermissionName`` アクセスに必要なパーミッションの名前 + です.詳しくは + `カスタムのパーミッション`_ を参照 + してください. + + デフォルトでは特定のパーミッションを + 必要としません. + ================================ ========================================= + +場合によって, ``SetEnv`` が mod_python の設定としてうまく働かない場合があ +ります.この原因はよくわかっていません. mod_python が +``DJANGO_SETTINGS_MODULE`` をうまく認識できない場合, ``SetEnv`` の代りに +``PythonOption`` を使ってみて下さい.以下の二つのディレクティブは同じ意味で +す:: + + SetEnv DJANGO_SETTINGS_MODULE mysite.settings + PythonOption DJANGO_SETTINGS_MODULE mysite.settings + + +.. _`認証システム`: ../authentication/ +.. _authentication system: ../authentication/ +.. _Subversion: http://subversion.tigris.org/ +.. _mod_dav: http://httpd.apache.org/docs/2.0/mod/mod_dav.html +.. _`カスタムのパーミッション`: ../authentication/#custom-permissions +.. _custom permissions: ../authentication/#custom-permissions diff --git a/api_stability.txt b/api_stability.txt new file mode 100644 index 0000000..c0d53a4 --- /dev/null +++ b/api_stability.txt @@ -0,0 +1,155 @@ +============ +API の安定性 +============ + +:revision-up-to: 4805 (release 0.96) + +Django はまだリリース 1.0 に到達していませんが, Django の公開 API の大半は +リリース 0.95 をもってほぼ安定したといえます.このドキュメントでは,1.0 の +リリースに向け,どの API を変更する予定か,どの API はそうでないかについて +説明します. + +.. _What "stable" means: + +APIの安定性とは +=============== + +ここでいう「安定」とは,以下のような意味をもちます: + + - 公開 API -- リンクからたどれるドキュメント内で開設されていて,メソッド + 名がアンダースコアで始まらないもの -- の配置や名前を変更する場合には, + 以前のバージョンとの互換性のための別名のメソッドを提供します. + + - API に新たな機能を追加する場合 -- これはよくあることですが -- でも, + 既存のメソッドの意味を無くしたり,変えたりすることはありません.換言す + れば,「安定」していても (必ずしも) 「完全」ではない,ということです. + + - すでに安定と宣言されている API を何らかの理由で削除したり移動したりせ + ねばならない場合,それらのメソッドは撤廃 (deprecated) とみなされ,少な + くともバージョン 1.1 までは API 中に残します.撤廃されたメソッドを呼び + 出した場合には警告メッセージを表示します. + + - 深刻なバグやセキュリティホールによってやむを得ない場合に限り,これらの + API に対して互換性のない変更を行います. + +安定な API +========== + +以下の API は安定です: + + - `キャッシュ`_ . + + - `カスタムテンプレートタグとライブラリ`_ (テンプレートの登録やロード方 + 法について例外的に変更される可能性があります). + + - `データベース照合`_ (バリデーションを除きます.下記参照). + + - `django-admin ユーティリティ`_ . + + - `FastCGI の組み込み`_ . + + - `フラットページ`_ . + + - `汎用ビュー`_ . + + - `国際化`_ . + + - `古いデータベースの組み込み`_ . + + - `モデル定義`_ (汎用リレーション: generic relation を除きます.下記参照). + + - `mod_python の組み込み`_ . + + - `リダイレクション`_ . + + - `リクエスト/レスポンスオブジェクト`_ . + + - `メールの送信`_ . + + - `セッション`_ . + + - `設定ファイル`_ . + + - `配信フィード`_ . + + - `テンプレート言語`_ (タグやフィルタに引数を渡す方法について例外的に変 + 更される可能性があります). + + - `トランザクション`_ . + + - `URL のディスパッチ`_ . + +上記のリストが Django API の大半に対応していることにお気づきでしょう.これ +はある意味真理です -- というのも, Django 1.0 に向けて計画されている変更は, +まだまだ水面下で行われているものか,あるいはわずかな部分的変更だからです. + +現時点では,Django の 90% が将来のバージョンと互換性を持っているといっても +よいでしょう. + +とはいえ,以下の API についてはまだ安定 *ではない* と考えており,変更される +可能性があります: + + - `フォームとバリデータ`_ は,おそらくバリデーション機能を備えたモデル + (validation-aware model) を使って完全に書き直すことになるでしょう. + + - `シリアライゼーション`_ 関連の機能は現在活発に開発されており,おそらく + 変更されることでしょう. + + - `認証`_ フレームワークはより柔軟なものに向けて変更中であり,必然的に + API への変更を伴うでしょう. + + - コア部分 (core) のオプションコンポーネントへの依存を避けるため,汎用リ + レーション (generic relation) をコアから,contrib の content-types パッ + ケージに移動させるでしょう. + + - コメント (comments) フレームワークにはまだドキュメントがありませんが, + このフレームワークは Django 1.0 以前に完全に書き直される予定です.劇的 + な変更ではないにしろ,かなりの変更が加わることでしょう. + +.. _caching: ../cache/ +.. _custom template tags and libraries: ../templates_python/ +.. _database lookup: ../db_api/ +.. _django-admin utility: ../django_admin/ +.. _fastcgi integration: ../fastcgi/ +.. _flatpages: ../flatpages/ +.. _generic views: ../generic_views/ +.. _internationalization: ../i18n/ +.. _legacy database integration: ../legacy_databases/ +.. _model definition: ../model_api/ +.. _mod_python integration: ../modpython/ +.. _redirects: ../redirects/ +.. _request/response objects: ../request_response/ +.. _sending email: ../email/ +.. _sessions: ../sessions/ +.. _settings: ../settings/ +.. _syndication: ../syndication/ +.. _template language: ../templates/ +.. _transactions: ../transactions/ +.. _url dispatch: ../url_dispatch/ +.. _forms and validation: ../forms/ +.. _serialization: ../serialization/ +.. _authentication: ../authentication/ + +.. _`キャッシュ`: ../cache/ +.. _`カスタムテンプレートタグとライブラリ`: ../templates_python/ +.. _`データベース照合`: ../db_api/ +.. _`django-admin ユーティリティ`: ../django_admin/ +.. _`FastCGI の組み込み`: ../fastcgi/ +.. _`フラットページ`: ../flatpages/ +.. _`汎用ビュー`: ../generic_views/ +.. _`国際化`: ../i18n/ +.. _`古いデータベースの組み込み`: ../legacy_databases/ +.. _`モデル定義`: ../model_api/ +.. _`mod_python の組み込み`: ../modpython/ +.. _`リダイレクション`: ../redirects/ +.. _`リクエスト/レスポンスオブジェクト`: ../request_response/ +.. _`メールの送信`: ../email/ +.. _`セッション`: ../sessions/ +.. _`設定ファイル`: ../settings/ +.. _`配信フィード`: ../syndication/ +.. _`テンプレート言語`: ../templates/ +.. _`トランザクション`: ../transactions/ +.. _`URL のディスパッチ`: ../url_dispatch/ +.. _`フォームとバリデータ`: ../forms/ +.. _`シリアライゼーション`: ../serialization/ +.. _`認証`: ../authentication/ diff --git a/authentication.txt b/authentication.txt new file mode 100644 index 0000000..d990f7d --- /dev/null +++ b/authentication.txt @@ -0,0 +1,1149 @@ +============================= +Django でのユーザ認証 +============================= + +:revision-up-to: 4805 (release 0.96) + +Django にはユーザ認証システムがついてきます. Django のユーザ認証システムは, +ユーザアカウント,グループ,パーミッションとクッキーベースのユーザセッショ +ンを扱えます.このドキュメントでは,ユーザ認証の仕組みについて説明します. + +.. _Overview: + +概要 +==== + +認証システムは以下の要素から成り立っています: + + * ユーザ (Users) + * パーミッション: あるユーザが特定のタスクを実行してよいかどうかを決め + る,バイナリ (yes/no) のフラグです. + * グループ (Groups): 複数のユーザに対してラベル付したり,認証を設定した + りするための一般的な方法です. + * メッセージ (Messages): 指定のユーザ(達) に対するメッセージをキューす + るための簡単な方法です. + +.. _Installation: + +インストール +============ + +認証のサポートは Django アプリケーションとして ``django.contrib.auth`` にバ +ンドルされています.インストールするには,以下のようにします: + + 1. ``INSTALLED_APPS`` 設定に ``'django.contrib.auth'`` を加えます. + 2. ``manage.py syncdb`` を実行します. + +``django-admin.py startproject`` が生成するデフォルトの ``settings.py`` ファ +イルの ``INSTALLED_APPS`` には,簡便のため ``'django.contrib.auth'`` が最初 +から入っています.この場合は,単に ``manage.py syncdb`` するだけでかまいま +せん. ``manage.py syncdb`` はその都度必要なものだけをインストールするので, +何度実行してもかまいません. + +``syncdb`` コマンドは必要なデータベーステーブルを作成し,インストール済みの +アプリケーションで必要な全てのパーミッションオブジェクトを作成します.また, +最初に実行したときには,ユーザにスーパユーザアカウントを作成するよう促しま +す. + +これだけで,認証サポートを使えるようになります. + +.. _Users: + +ユーザ (User) +=============== + +ユーザは標準的な Django のモデル (model) として表現されています.ユーザのモ +デルは `django/contrib/auth/models.py`_ にあります. + +.. _django/contrib/auth/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py + +API リファレンス +------------------ + +フィールド +~~~~~~~~~~~ + +``User`` オブジェクトには以下のフィールドがあります: + + * ``username`` -- 必須です.30 文字以下の文字列で,英数字 (アルファベッ + ト,数字,アンダースコア) だけを使えます. + * ``first_name`` -- オプションです.30 文字以下です. + * ``last_name`` -- オプションです. 30 文字以下です. + * ``email`` -- オプションです. E-mail アドレスです. + * ``password`` -- 必須です.パスワードのメタデータであるハッシュ値です + (Django では生のパスワードを保存しません).生のパスワードは任意の長さ + でよく,どんな文字が入っていても構いません.詳しくは以下の + `パスワード`_ の節を参照して下さい. + * ``is_staff`` -- Bool 値です.この値が真なら,ユーザは admin サイトに + アクセスできます. + * ``is_active`` -- Bool 値です.この値が真なら,ログインにこのアカウン + トを使えます.アカウントを削除する代わりに,この値を ``False`` に + 設定してください. + * ``is_superuser`` -- Bool 値です.この値が真なら,ユーザは明示的な指定 + がなくても全てのパーミッションを得ます. + * ``last_login`` -- ユーザが最後にログインした時刻を表す datetime オブ + ジェクトです.デフォルトではログイン時現在の日付/時刻になります. + * ``date_joined`` -- アカウントの作成された時刻を表す datetime オブジェ + クトです.デフォルトではアカウント作成時現在の日付/時刻になります. + +メソッド +~~~~~~~~~~ + +``User`` オブジェクトには ``groups`` と ``user_permissions`` という二つの多 +対多のフィールドがあります.この関係性のために, ``User`` オブジェクトは他 +の `Django モデル`_ と同じようにして,関連づけされたオブジェクトにアクセス +できます:: + + myuser.groups = [group_list] + myuser.groups.add(group, group,...) + myuser.groups.remove(group, group,...) + myuser.groups.clear() + myuser.user_permissions = [permission_list] + myuser.user_permissions.add(permission, permission, ...) + myuser.user_permissions.remove(permission, permission, ...] + myuser.user_permissions.clear() + +自動的に生成されるこれらの API に加え, ``User`` オブジェクトには以下のカス +タムメソッドがあります: + + * ``is_anonymous()`` -- 常に ``False`` を返します. ``User`` オブジェク + トを ``AnonymousUser`` オブジェクトと区別する手段の一つです. 通常は, + ``is_authenticated()`` メソッドを使うようにしてください. + + * ``is_authenticated()`` -- 常に ``True`` を返します.ユーザを認証済み + かどうかを調べる一つの方法です.このメソッドの戻り値は,ユーザが正し + いパーミッションを持っているか,あるいはアクティブなユーザであるかど + うかに関係なく,ユーザが正しいユーザ名とパスワードを入力したことだけ + を示します. + + * ``get_full_name()`` -- ``first_name`` と ``last_name`` をスペースでつ + なげた文字列を返します. + + * ``set_password(raw_password)`` -- 渡された文字列をハッシュ化し,ユー + ザのパスワードに設定します. ``User`` オブジェクトの保存は行いません. + + * ``check_password(raw_password)`` -- 渡された文字列がこのユーザの正し + い文字列ならば ``True`` を返します.(このメソッドは比較時にパスワード + のハッシュ処理を行います) + + * ``get_group_permissions()`` -- ユーザが自分の属するグループから得てい + るパーミッションを表す文字列からなるリストを返します. + + * ``get_all_permissions()`` -- ユーザ自身のもつパーミッションと,ユーザ + の属するグループのパーミッションの両方からなるリストを返します. + + * ``has_perm(perm)`` -- ユーザが特定のパーミッションを持っている場合に + ``True`` を返します. パーミッション名 perm は ``"package.codename"`` + のような形式で表します. + ユーザがアクティブでない場合,このメソッドは常に ``False`` を返します. + + * ``has_perms(perm_list)`` -- ユーザが perm_list 内のパーミッションのい + ずれかを持っている場合に ``True`` を返します.各々のパーミッション名 + は ``"package.codename"`` のような形式で表します. + ユーザがアクティブでない場合,このメソッドは常に ``False`` を返します. + + * ``has_module_perms(package_name)`` -- ユーザが指定のパッケージ名 + (Django アプリケーションラベル: Django app label) の何らかのパーミッ + ションを持っていれば ``True`` を返します. + ユーザがアクティブでない場合,このメソッドは常に ``False`` を返します. + + * ``get_and_delete_messages()`` -- ユーザのキューに入っているメッセージ + を返し,入っていたメッセージをキューから取り除きます. + + * ``email_user(subject, message, from_email=None)`` -- ユーザに e-mail + を送信します. ``from_email`` が ``None`` の場合, Django は + `DEFAULT_FROM_EMAIL`_ 設定を使います. + + * ``get_profile()`` -- ユーザのサイト固有のプロファイル (site-specific + profile) を返します.プロファイルを使えないサイトでは + ``django.contrib.auth.models.SiteProfileNotAvailable`` を送出します. + +.. _Django model: ../model_api/ +.. _Django モデル: ../model-api/ +.. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email +.. DEFAULT_FROM_EMAIL: + ../settings/#default-from-email + +.. _Manager functions: + +マネジャ関数 +~~~~~~~~~~~~ + +``User`` オブジェクトの ``objects`` 属性は ``models.Manager`` クラスのサブ +クラス ``UserManager`` クラスで実装されています. ``UserManager`` クラスは +通常のモデルが ``objects`` 属性を介してできること (``get`` や ``filter`` の +ようなデータベースへのアクセス) に加えて,以下のヘルパー関数を提供していま +す: + + * ``create_user(username, email, password)`` -- ユーザを生成して保存し, + 生成された ``User`` を返します. ``username``, ``email`` および + ``password`` は指定した値になり, ``is_active`` は ``True`` に設定さ + れます. + + 使用例は `ユーザの作成`_ を参照してください. + + * ``make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')`` + 指定した長さのランダムなパスワードを生成して返します.パスワードに使 + える文字は文字列で指定します.(``allowed_chars`` のデフォルト値は,ユー + ザの見間違いを防ぐため ``"I"`` と ``"I"`` に似た文字を除いてあります.) + +基本的な使い方 +-------------- + +ユーザの作成 +~~~~~~~~~~~~~~ + +ユーザを作成する一番基本的な方法は,オブジェクトマネージャの +``create_user`` ヘルパー関数を使う方法です:: + + >>> from django.contrib.auth.models import User + >>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword') + # この操作で,User オブジェクト user を保存できるようになります. + # 他のフィールドを変更したければ,属性を変更します. + >>> user.is_staff = True + >>> user.save() + +パスワードの変更 +~~~~~~~~~~~~~~~~~~ + +パスワードの変更には ``set_password()`` を使います:: + + >>> from django.contrib.auth.models import User + >>> u = User.objects.get(username__exact='john') + >>> u.set_password('new password') + >>> u.save() + +特別な意図のない限り, ``password`` 属性を直接設定しないでください.これに +ついては次節で説明します. + + +.. _Passwords: + +パスワード +------------- + +``User`` オブジェクトの ``password`` フィールドは:: + + hashtype$salt$hash + +のような形式の文字列,すなわちハッシュ方式 (hashtype),ハッシュソルト +(salt),そしてハッシュ値 (hash) をドル記号 (``"$"``) で分割した文字列になり +ます. + +ハッシュ形式は ``sha1`` (デフォルト) または ``md5`` であり,それぞれパスワー +ドの一方向ハッシュ化アルゴリズムを表します.ソルトは生のパスワード文字列か +らハッシュを生成するときに味付け (salt) しておくためのランダムな文字列です. + +例えば:: + + sha1$a1976$a36cc8cbf81742a8fb52e221aaeab48ed7f58ab4 + +``User.set_password()`` および ``User.check_password()`` 関数は,これらの値 +の設定やチェックを背後で行っています. + +バージョン 0.90 のような以前の Django では,パスワードソルトなしの単純な +MD5 ハッシュを使っていました.この形式は,以前のバージョンとの互換性を持た +せるためにまだサポートしています.ただし,古いパスワードのユーザに対して +``check_passwword()`` が成功した時に自動的に新しい形式に変換します. + +.. _Anonymous users: + +匿名ユーザ (Anonymous users) +------------------------------- + +``django.contrib.auth.models.AnonymousUser`` は +``django.contrib.auth.models.User`` インタフェースを実装したクラスですが, +以下の点で ``User`` と異なります: + + * ``id`` は常に ``None`` です. + * ``is_anonymous()`` は ``False`` ではなく ``True`` を返します. + * ``is_authenticated()`` は ``True`` ではなく ``False`` を返します. + * ``has_perm()`` は常に ``False`` を返します. + * ``set_password()``, ``check_password()``, ``save()``, ``delete``, + ``set_groups()`` および ``set_permissions()`` は + ``NotImplementedError`` を送出します. + +おそらく,実践上意識して ``AnonymousUser`` オブジェクトを使う必要はないはず +です.とはいえ,匿名ユーザは次節で述べるような形で Web リクエストで使われて +います. + +.. _Creating superusers: + +スーパユーザの作成 +------------------ + +``INSTALLED_APPS`` に ``'django.contrib.auth'`` を追加した直後の +``manage.py syncdb`` では,スーパユーザの作成を促すプロンプトを表示します. +また,後でスーパユーザを作成したい場合には, ``creater_superuser.py`` ユー +ティリティを使えます.以下のコマンドを実行してください:: + + python /path/to/django/contrib/auth/create_superuser.py + +``/path/to/`` は自分のシステムの Django コードベースへのパスに応じて読み変 +えて下さい. + + +.. _Authentication in Web requests: + +Web リクエストに対する認証 +============================== + +ここまでのドキュメントは,認証関連のオブジェクトを操作するための低水準の +API について扱ってきました.より高水準の API では, Django はこれらの認証フ +レームワークを `リクエストオブジェクト`_ システム内にフックできます. + + +まず, ``SessionMiddleware`` および ``AuthenticationMiddleware`` を +``MIDDLEWARE_CLASSES`` 設定に追加して,これらのミドルウェアをインストールし +ます.詳しくは `セッションのドキュメント`_ を参照してください. + +ミドルウェアをインストールしたら,ビューから ``request.user`` にアクセスで +きるようになります. ``request.user`` は現在ログインしているユーザの +``User`` オブジェクトを表します.ユーザがログインしていなければ, +``request.user`` は ``AnonymousUser`` のインスタンスになります(前節を参照し +てください).ログインユーザと匿名ユーザは, ``is_authenticated()`` で以下の +ように区別できます:: + + if request.user.is_authenticated(): + # Do something for authenticated users. + else: + # Do something for anonymous users. + +.. _`リクエストオブジェクト`: ../request_response/#httprequest-objects +.. _`セッションのドキュメント`: ../sessions/ +.. _request objects: ../request_response/#httprequest-objects +.. _session documentation: ../sessions/ + +.. _Manually checking a user's password: + +ユーザのパスワードを手動で調べる +-------------------------------- + +ユーザ認証を手動で行うために平文パスワードとデータベース上のハッシュ化パス +ワードを比較したい場合には, ``django.contrib.auth.models.check_password`` +という便宜関数を使えます.この関数は,調べたい平文パスワードと,比較対象の +データベースに格納されているユーザの ``password`` フィールド全体の二つの引 +数をとり,二つが一致すれば ``True`` を,そうでなければ ``False`` を返します. + +.. _How to log a user in: + +ユーザをログインさせる +----------------------- + +Django では, ``django.contrib.auth`` の中で, ``authenticat()`` と +``login()`` という二つの関数を提供しています. + +あるユーザ名とパスワードに対する認証を行うには, ``authenticate()`` を使っ +てください.この関数は二つのキーワード引数, ``username`` と ``password`` +をとり,ユーザ名に対してパスワードが有効であった場合に ``User`` オブジェク +トを返します.パスワードが無効だった場合には, ``authenticate()`` は +``None`` を返します.例えば:: + + from django.contrib.auth import authenticate + user = authenticate(username='john', password='secret') + if user is not None: + if user.is_active: + print "You provided a correct username and password!" + else: + print "Your account has been disabled!" + else: + print "Your username and password were incorrect." + + +ユーザをログインさせるには,ビューの中で ``login()`` を使ってください.この +関数は ``HttpRequest`` オブジェクトと ``User`` オブジェクトを引数にとります. +``login()`` は Django のセッションフレームワークを使って,ユーザの ID をセッ +ションに保存します.従って,上でも述べたように,セッションミドルウェアをイ +ンストールしておかねばなりません. + +以下の例は ``authenticate()`` と ``login()`` の使い方を示しています:: + + from django.contrib.auth import authenticate, login + + def my_view(request): + username = request.POST['username'] + password = request.POST['password'] + user = authenticate(username=username, password=password) + if user is not None: + if user.is_active: + login(request, user) + # Redirect to a success page. + else: + # Return a 'disabled account' error message + else: + # Return an error message. + +.. _How to log a user out: + +ユーザをログアウトさせる +------------------------ + +``django.contrib.auth.login()`` でログインしたユーザをログアウトさせるには, +ビューの中で ``django.contrib.auth.logout()`` を使ってください.この関数は, +``HttpRequest`` オブジェクトを引数に取り,戻り値を持ちません.例を以下に示 +します:: + + from django.contrib.auth import logout + + def logout_view(request): + logout(request) + # Redirect to a success page. + +ユーザがログインしていなくても ``logout()`` はエラーを送出しないことに注意 +してください. + +.. _Limiting access to logged-in users: + +ログインユーザだけがアクセスできるように制限をかける +---------------------------------------------------- + +.. _The raw way: + +生真面目な方法 +~~~~~~~~~~~~~~~~~ + +ページへのアクセスを制限する単純で生真面目な方法は, +``request.user.is_authenticated()`` をチェックして,ログインページにリダイ +レクトするというものです:: + + from django.http import HttpResponseRedirect + + def my_view(request): + if not request.user.is_authenticated(): + return HttpResponseRedirect('/login/?next=%s' % request.path) + # ... + +...あるいは,エラーメッセージを出しても構いません:: + + def my_view(request): + if not request.user.is_authenticated(): + return render_to_response('myapp/login_error.html') + # ... + +.. _The login_required decorator: + +login_required デコレータ +~~~~~~~~~~~~~~~~~~~~~~~~~ + +手間を省くために, ``login_required`` デコレータを使えます:: + + from django.contrib.auth.decorators import login_required + + def my_view(request): + # ... + my_view = login_required(my_view) + +Python 2.4 で登場したよりコンパクトなデコレータ構文を使った例を以下に示しま +す:: + + from django.contrib.auth.decorators import login_required + + @login_required + def my_view(request): + # ... + +``login_required`` が行うのは以下のような処理です: + + * ユーザがログインしていなければ, ``/accounts/login/`` にリダイレクト + します.このとき,現在のクエリの絶対 URL を ``next`` に入れ,例えば + ``/accounts/login/?next=/polls/3/`` のようにします. + * ユーザがログインしていれば, ビューを普通に実行します.ビューコードの + 中では,ユーザがログインしているものとみなして構いません. + + +ただし,これを行うには ``/accounts/login/`` に適切な Django のビュー関数を +対応づけておかねばなりません.例えば URLconf に以下のような行を設定します:: + + (r'^accounts/login/$', 'django.contrib.auth.views.login'), + +こうしておくと, ``django.contrib.auth.views.login`` は以下のような処理を行 +います: + + * ``GET`` で呼び出されると,同じ URL に対して POST を行うためのログイン + フォームを表示します.これについては後でもう少し説明します. + + * ``POST`` で呼び出されると,ユーザのログイン処理を試みます.ログインに + 成功すると,ビューは ``next`` に示された URL にリダイレクトします + ``next`` を指定しない場合, ``/accounts/profile/`` にリダイレクトしま + す (現状ではハードコードされたページです).ログインに失敗すると,ログ + インフォームを再度表示します. + +開発者は ``registration/login.html`` という名前のテンプレート上でログイン +フォームを提供せねばなりません. Django はこのテンプレートに,以下の 3 つの +テンプレートコンテキスト変数を渡します: + + * ``form``: ログインフォームを表現する ``FormWrapper`` オブジェクトです. + ``FormWrapper`` オブジェクトの詳細は `forms のドキュメント`_ を参照し + てください. + * ``next``: ログイン成功後にリダイレクトされる先の URL です. URL には + クエリ文字列を含めてかまいません. + * ``site_name``: ``SITE_ID`` によって決定される現在の ``Site`` の名前で + す. `site フレームワークのドキュメント`_ を参照してください. + +``registration/login.html`` テンプレートを呼び出したくないのなら,URLconf +を通じて外部パラメタ ``template_name`` をビューに渡してください.例えば, +``myapp/login.html`` を使いたければ,URLconf の行は以下のようになります:: + + (r'^accounts/login/$', 'django.contrib.auth.views.login', + {'template_name': 'myapp/login.html'}), + +編集の雛型にできるような ``registration/login.html`` テンプレートの例を以下 +に示します.このテンプレートは, ``content`` ブロックの定義された +``base.html`` があるという前提で書かれています:: + + {% extends "base.html" %} + + {% block content %} + + {% if form.has_errors %} +

Your username and password didn't match. Please try again.

+ {% endif %} + +
+ + + +
{{ form.username }}
{{ form.password }}
+ + + +
+ + {% endblock %} + +.. _`forms のドキュメント`: ../forms/ +.. _`site フレームワークのドキュメント`: ../sites/ +.. _forms documentation: ../forms/ +.. _site framework docs: ../sites/ + +.. _Other built-in views: + +その他の組み込みビュー +----------------------- + +認証システムでは, ``login`` ビューの他にも便利なビューをいくつか提供してい +ます: + +``django.contrib.auth.views.logout`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**説明:** + +ユーザをログアウトさせます. + +**オプション引数:** + + * ``template_name``: ログアウトページのテンプレートの完全な名前です. + この引数を省略すると,デフォルト値の ``registration/logged_out.html`` + を使います. + + +**テンプレートコンテキスト:** + + * ``title``: "Logged out" という文字列を翻訳した値になります. + +``django.contrib.auth.views.logout_then_login`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**説明:** + +ユーザをログアウトさせてから,ログインページにリダイレクトします. + +**オプション引数:** + + * ``login_url``: ログインページへのリダイレクト先です. + この引数を省略すると,デフォルト値の ``/accounts/login/`` を使います. + +``django.contrib.auth.views.password_change`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**説明:** + +ユーザがパスワードを変更できるようにします. + +**オプション引数:** + + * ``template_name``: パスワード変更ページのテンプレートの完全な名前です. + この引数を省略すると,デフォルト値の + ``registration/password_change_form.html`` を使います. + +**テンプレートコンテキスト:** + + * ``form``: パスワード変更のためのフォームです. + +``django.contrib.auth.views.password_change_done`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**説明:** + +ユーザがパスワードを変更した後のページを表示するためのビューです. + +**オプション引数:** + + * ``template_name``: パスワード変更完了ページのテンプレートの完全な名前 + です.この引数を省略すると,デフォルト値の + ``registration/password_change_done.html`` を使います. + +``django.contrib.auth.views.password_reset`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**説明:** + +ユーザがパスワードをリセットできるようにします.また,新たなパスワードをメー +ルで送信します. + +**オプション引数:** + + * ``template_name``: パスワードリセットページのテンプレートの完全な名前 + です.この引数を省略すると,デフォルト値の + ``registration/password_reset_form.html`` を使います. + + * ``email_template_name``: 新しいパスワードを e-mail で送信する際に使う + テンプレートの完全な名前です.この引数を省略すると,デフォルト値の + ``registration/password_reset_email.html`` を使います. + +**テンプレートコンテキスト:** + + * ``form``: パスワードリセットのためのフォームです. + +``django.contrib.auth.views.password_reset_done`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**説明:** + +ユーザがパスワードをリセットした後のページを表示するためのビューです. + +**オプション引数:** + + * ``template_name``: パスワードリセット完了ページのテンプレートの完全な + 名前です.この引数を省略すると,デフォルト値の + ``registration/password_reset_done.html`` を使います. + +``django.contrib.auth.views.redirect_to_login`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**説明:** + +ログインページにリダイレクトし,ログインに成功したら別の URL に戻れるように +するためのビューです. + +**必須の引数:** + + * ``next``: ログイン成功後のリダイレクト先 URL です. + +**オプション引数:** + + * ``login_url``: ログインページへのリダイレクト先です. + この引数を省略すると,デフォルト値の ``/accounts/login/`` を使います. + +.. _Built-in manipulators: + +組み込みマニピュレータ +---------------------- + +組み込みビューを使いたくないけれども,マニピュレータを書かずに済ませたい場 +合のために,認証システムでは組み込みのマニピュレータをいくつか提供していま +す: + + * ``django.contrib.auth.forms.AdminPasswordChangeForm``: Admin インタ + フェースでユーザのパスワード変更に使われているマニピュレータです. + + * ``django.contrib.auth.forms.AuthenticationForm``: ユーザをログインさ + せるためのマニピュレータです. + + * ``django.contrib.auth.forms.PasswordChangeForm``: ユーザにパスワード + 変更させるためのマニピュレータです. + + * ``django.contrib.auth.forms.PasswordResetForm``: パスワードをリセット + し,新たなパスワードを送信するためのマニピュレータです. + + * ``django.contrib.auth.forms.UserCreationForm``: 新たなユーザを作成す + るためのマニピュレータです. + + +.. _Limiting access to logged-in users that pass a test: + +テストにパスしたログインユーザだけがアクセスできるように制限をかける +-------------------------------------------------------------------- + +特定のパーミッションやその他のテストの結果に応じたアクセスの制限には,前節 +で説明したの本質的に同じことをします. + +一番簡単な方法は,ビュー内で直接 ``request.user`` に対するテストを実行する +というものです.例えば,以下のビューではユーザがログイン済みで,かつ +``polls.can_vote`` というパーミッションを持っているかチェックします:: + + def my_view(request): + if not (request.user.is_authenticated() and \ + request.user.has_perm('polls.can_vote')): + return HttpResponse("You can't vote in this poll.") + # ... + +``user_passes_test`` デコレータを使えば,手間を省けます:: + + from django.contrib.auth.decorators import user_passes_test + + def my_view(request): + # ... + my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'))(my_view) + +ここでは,簡単な例としてパーミッションのテストに ``user_passes_test`` を使っ +ていますが,単にあるユーザがあるパーミッションを有しているかをテストしたい +だけなら,後で解説する ``permission_required()`` デコレータを使えます. + +Python 2.4 のデコレータ構文ならこうなります:: + + from django.contrib.auth.decorators import user_passes_test + + @user_passes_test(lambda u: u.has_perm('polls.can_vote')) + def my_view(request): + # ... + +``user_passes_test`` には必須の引数が一つあります.この引数は, ``User`` を +引数に取り,ユーザにページのビューを許可する場合には ``True`` を返す呼び出 +し可能オブジェクトでなければなりません. ``user_passes_test`` は ``User`` +が匿名かどうかを自動的に調べないので注意してください. + +``user_passes_test()`` はオプションの引数として ``login_url`` をとります. +この引数を使うとログインページへの URL を指定できます (デフォルトでは +``/accounts/login/`` になります). + +Python 2.3 風の構文で書いた例を示します:: + + from django.contrib.auth.decorators import user_passes_test + + def my_view(request): + # ... + my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')(my_view) + +Python 2.4 風の構文で例を書くと以下のようになります:: + + from django.contrib.auth.decorators import user_passes_test + + @user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/') + def my_view(request): + # ... + +.. _The permission_required decorator: + +permission_required デコレータ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +あるユーザが特定のパーミッションを有しているかのチェックは,比較的よくある +操作なので, Django はショートカットとして ``permission_required()`` という +デコレータを用意しています.このデコレータを使うと,上の例は以下のように書 +き直せます:: + + from django.contrib.auth.decorators import permission_required + + def my_view(request): + # ... + + my_view = permission_required('polls.can_vote')(my_view) + +``permission_required()`` もまた, ``login_url`` を引数に取れます.例えば:: + + from django.contrib.auth.decorators import permission_required + + def my_view(request): + # ... + my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view) + +``login_required`` デコレータと同様, ``login_url`` のデフォルト値は +``'/accounts/login/'`` です. + + +.. _Limiting access to generic views: + +アクセスを汎用ビューに制限する +------------------------------ + +アクセスを `汎用ビュー`_ に制限するには,ビューを囲む薄いラッパコードを書き, +URLconf を変更して,ジェネリックビュー自体ではなくラッパコードを指すように +します.例えば:: + + from django.views.generic.date_based import object_detail + + @login_required + def limited_object_detail(*args, **kwargs): + return object_detail(*args, **kwargs) + +.. _`汎用ビュー`: ../generic_views/ +.. _generic view: ../generic_views/ + +.. _Permissions: + +パーミッション (Permission) +=========================== + +Django には単純なパーミッション機構がついてきます.このパーミッション機構は +特定のユーザやユーザのグループに対してパーミッションを結びつける手段を提供 +します. + +パーミッション機構は Django の admin サイトでも使われていますが,自作のコー +ド内でも自由に使えます. + +Django の admin サイトでは,以下のようなパーミッションを使っています: + + * "add" フォームをビューし,オブジェクトを追加するためのアクセスを,そ + の型のオブジェクトの "add" パーミッションを持つユーザに制限しています. + * 変更リストをビューし,"change" フォームをビューしてオブジェクトを変更 + するためのアクセスを,その型のオブジェクトの "change" パーミッション + を持つユーザに制限しています. + * あるオブジェクトを削除するためのアクセスを,その型のオブジェクトの + "delete" パーミッションを持つユーザに制限しています. + +パーミッションはオブジェクトインスタンスごとではなく,オブジェクトの型ごと +にグローバルに設定されます.例えば,「Mary はニュース記事を変更できる」のよ +うには書けますが,現状では,「Mary はニュース記事を変更できる.ただし彼女が +書いた分だけ」とか,「Mary はある状態にある記事か,ある日時に出版されたか, +ある ID の記事だけを変更できる」のようには書けません.後者の機能については +は,現在 Django の開発者達が議論中です. + +.. _Default permissions: + +デフォルトのパーミッション +-------------------------- + +``class Admin`` セットを持つ Django モデルには,三つの基本的なパーミッショ +ンである, add, create, delete が自動的に生成されます. +``manage.py syncdb`` を実行したとき,背後では,これらのパーミッションが自動 +的に ``auth_permission`` データベーステーブルに追加されます. +``django-admin.py sqlinitialdata [app]`` を実行すると,追加を行っている +``INSERT`` 文そのものを閲覧できます. + +``manage.py syncdb`` を実行した際,モデルに ``class Admin`` セットがないと, +パーミッションは生成されないので気を付けて下さい.この後でデータベースを初 +期化して ``class Admin`` をモデルに追加した場合, ``manage.py sycndb`` を再 +度実行せねばなりません.このコマンドは,インストール済みのアプリケーション +に欠けているパーミッションを生成します. + +.. _Custom permissions: + +カスタムのパーミッション +------------------------- + +カスタムのパーミッションを生成するには, ``permissions`` という +`モデルのメタ属性`_ を使います. + +この例では,三つのカスタムパーミッションを生成しています:: + + class USCitizen(models.Model): + # ... + class Meta: + permissions = ( + ("can_drive", "Can drive"), + ("can_vote", "Can vote in elections"), + ("can_drink", "Can drink alcohol"), + ) + +この定義の役割は, ``syncdb`` を実行したときに追加のパーミッションを追加 +することだけです. + + +.. _`モデルのメタ属性`: ../model-api/#meta-options +.. _model Meta attribute: + ../model_api/#meta-options + +API リファレンス +----------------- + +ユーザと同様,パーミッションは Django モデルとして実装されています.実装は +`django/contrib/auth/models.py`_ にあります. + +.. _django/contrib/auth/models.py: + http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py + +フィールド +~~~~~~~~~~~~ + +``Permission`` オブジェクトには以下のフィールドがあります: + + * ``name`` -- 必須です.50 文字以下です.例: ``'Can vote'`` + * ``content_type`` -- 必須です.インストール済みの Django モデルのレコー + ドが入った ``django_content_type`` データベーステーブルへの参照です. + * ``codename`` -- 必須です. 100 文字以下です.例: ``'can_vote'`` + +メソッド +~~~~~~~~~ + +``Permission`` オブジェクトは,他の `Django モデル`_ と同じく,標準的なデー +タアクセスメソッドを備えています. + +認証データのテンプレート上での扱い +===================================== + +``RequestContext`` を使っている場合,ログインユーザとそのパーミッションに +`テンプレートコンテキスト`_ (template context) を使ってアクセスできます. + +.. class:: tips +.. admonition:: 技術的な話題 + + デフォルトの設定では,テンプレートコンテキストに ``RequestContext`` を使 + うようになっていて,*かつ* ``TEMPLATE_CONTEXT_PROCESSORS`` の設定に + ``"django.core.context_processors.auth"`` が入っています.この場合にのみ, + 上記の変数をテンプレートコンテキストの中で使えるようになります.詳しくは + `RequestContext のドキュメント`_ を参照してください. + + .. _`RequestContext のドキュメント`: + ../templates_python/#subclassing-context-requestcontext + .. _RequestContext docs: + ../templates_python/#subclassing-context-requestcontext + + +.. Users: + +ユーザ +------ + +現在のログインユーザは, ``User`` インスタンスであっても ``AnonymousUser`` +インスタンスであっても,テンプレート変数 ``{{ user }}`` に入ります:: + + {% if user.is_authenticated %} +

Welcome, {{ user.username }}. Thanks for logging in.

+ {% else %} +

Welcome, new user. Please log in.

+ {% endif %} + + +.. _Persmissions: + +パーミッション +-------------- + +現在のログインユーザのパーミッションはテンプレート変数 ``{{ perms }}`` に入っ +ています.この変数はパーミッションオブジェクトをテンプレートで扱いやすくす +るためのプロキシ (proxy) である, +``django.core.context_processors.PermWrapper`` のインスタンスです. + +``{{ perms }}`` オブジェクトに対して 1 段の属性参照を行うと,実際には +``User.has_module_perms`` へのプロキシになっています.例えば下記の例は,ロ +グインユーザが ``foo`` というアプリケーションへのパーミッションを持っている +場合に ``True`` を表示します:: + + {{ perms.foo }} + +2 段の属性参照は ``User.has_perm`` へのプロキシです.以下の例では,ログイン +ユーザが ``foo.can_vote`` へのパーミッションを持つ場合に ``True`` を表示し +ます:: + + {{ perms.foo.can_vote }} + +こうして,テンプレート内で ``{% if %}`` 文を使ってチェックを行えます:: + + {% if perms.foo %} +

You have permission to do something in the foo app.

+ {% if perms.foo.can_vote %} +

You can vote!

+ {% endif %} + {% if perms.foo.can_drive %} +

You can drive!

+ {% endif %} + {% else %} +

You don't have permission to do anything in the foo app.

+ {% endif %} + +.. _`テンプレートコンテキスト`: ../templates_python/ +.. _template context: ../templates_python/ + +.. _Groups: + +グループ (Group) +================== + +グループは,パーミッションを適用するユーザのカテゴリを作ったり,一連のユー +ザに何らかのラベルを適用するための汎用的な手段です.あるユーザは複数のグルー +プに所属できます. + +グループに所属したユーザは,そのグループに許可されているパーミッションを自 +動的に得ます.例えば, ``Site editors`` というグループに +``can_edit_home_page`` というパーミッションをがあれば,そのグループに属する +ユーザはみな, ``can_edit_home_page`` のパーミッションを持ちます. + +パーミッションだけではなく,グループはユーザをカテゴリに分けてラベルを付け +たり,機能を拡張したりできます.例えば, ``'特別なユーザ'`` のグループを作 +成して,そのグループのユーザ向けに,例えばサイト内のメンバー限定エリアへの +アクセスを提供したり,メンバーだけに e-mail メッセージを送るといった,特別 +な処理を行うコードを書けます. + +.. _Messages: + +メッセージ (Message) +==================== + +メッセージシステムは,任意のユーザ宛のメッセージをキューしておく軽量な方法 +です. + +メッセージは ``User`` に関連づけられます.メッセージには有効期限やタイムス +タンプの概念はありません. + +メッセージは Django admin で何らかの処理の成功を知らせる際に使われています. +例えば, ``"The poll Foo was created successfully."`` はメッセージで実現さ +れています. + +メッセージの API は単純です: + + * メッセージの追加には, + ``user_obj.message_set.create(message='message_text')`` + を使います. + * メッセージの取得と削除には,``user_obj.get_and_delete_messages()`` + を使います.このメソッドは,該当ユーザのキューに溜っている + ``Message`` オブジェクトがあれば,リストにして返し,キュー内の + メッセージを削除します. + +このビューの例では,システムはプレイリストの作成後に表示されるメッセージを +保存します:: + + def create_playlist(request, songs): + # Create the playlist with the given songs. + # ... + request.user.message_set.create( + message="Your playlist was added successfully.") + return render_to_response("playlists/create", + context_instance=RequestContext(request)) + +``RequestContext`` を使うと,現在のログインユーザとそのメッセージをテンプレー +ト変数 ``{{ messages }}`` として使えます.メッセージを表示するためのテンプ +レートコード例を示します:: + + {% if messages %} + + {% endif %} + +``RequestContext`` は ``get_and_delete_messages`` を背後で呼び出すので,メッ +セージは表示されなくても消去されることに注意してください. + +最後に,このメッセージフレームワークはユーザデータベースに登録されているユー +ザに対してしか動作しないことに注意して下さい.匿名ユーザにメッセージを送る +には, `セッションフレームワーク`_ を使って下さい. + +.. _`セッションフレームワーク`: ../sessions/ +.. _session framework: ../sessions/ + + +.. _Other authentication sources: + +他の認証データソースを使う +========================== + +ほとんどのケースでは, Django についてくる認証メカニズムで十分のはずですが, +場合によっては別の認証データソース (authentication source) をフックしたい, +すなわち,Django 外のユーザ名やパスワードデータや認証メソッドを使いたいよう +なケースもあることでしょう. + +例えば,会社が LDAP 構成を使って社員のユーザ名やパスワードを管理していると +しましょう.ネットワーク管理者にとっても,またユーザ自身にとっても, LDAP +とDjango ベースのアプリケーションの双方で別々のアカウントを維持するのはいさ +さか骨の折れる作業です. + +こうした状況を扱うために, Django の認証システムは別の認証ソースをプラグイ +ンできるようになっています. Django がデフォルトで使っているデータベースの +スキームをオーバライドしたり,デフォルトのシステムを他のシステムと並列して +動作させたりできます. + +.. _Specifying authentication backends: + +他の認証バックエンドを指定する +------------------------------ + +舞台裏では, Django は認証に使う「認証バックエンド」のリストを維持していま +す.前述の「ユーザをログインさせる」で説明したように +``django.contrib.auth.authenticate()`` を呼び出すと,Django は全ての認証バッ +クエンドにわたって認証テストを試みます.最初の認証メソッドに失敗すると次の +認証バックエンド,という具合にして,認証に成功しない限り,全てのバックエン +ドを試すまで続けます. + +認証に使うバックエンドのリストは ``AUTHENTICATION_BACKENDS`` 設定に指定しま +す.この値は Python モジュールパス名からなるタプルで,認証方法を実装したク +ラスの名前を指定します.認証クラスは Python パス上のどこにあってもかまいま +せん. + +デフォルトでは, ``AUTHENTICATION_BACKENDS`` の値は:: + + ('django.contrib.auth.backends.ModelBackend',) + +に設定されています.このクラスは, Django のユーザデータベースをチェックす +る認証スキームです. + +``AUTHENTICATION_BACKENDS`` の順番には意味があり,同じユーザ名とパスワード +が複数のバックエンドで有効な値であったとしても, Django は最初にユーザ名と +パスワードがマッチした時点で認証処理を停止します. + +.. _Writing an authentication backend: + +認証バックエンドを作成する +-------------------------- + +認証バックエンドの実体は, ``get_user(id)`` と +``authenticate(**credentials)`` という二つのメソッドを実装したクラスです. + +``get_user`` メソッドはユーザ名,データベース ID などを表す引数 ``id`` とり, +対応する ``User`` オブジェクトを返します. + +``authenticate`` メソッドは証明情報,すなわちユーザ名とパスワードなどをキー +ワード引数の形で受け取ります.ほとんどの場合,以下のような形式をとります:: + + class MyBackend: + def authenticate(self, username=None, password=None): + # Check the username/password and return a User. + +以下のようにトークンに対する認証を行うようにも書けます:: + + class MyBackend: + def authenticate(self, token=None): + # Check the token and return a User. + +どちらの方法でも, ``authenticate`` は受け取った証明情報をチェックし,証明 +情報が有効な場合,対応する ``User`` オブジェクトを返さねばなりません.証明 +情報が無効なら, ``None`` を返します. + +Django の admin システムは,冒頭で説明した Django の ``User`` オブジェクト +と強くカップリングしています.従って,今のところ自作の認証バックエンドを扱 +うには, (LDAP ディレクトリや外部の SQL データベースなどのような) 別のバッ +クエンド上のユーザに対して Django の ``User`` オブジェクトを生成するのがベ +ストです.あらかじめスクリプトを書いておいてもよいですし,ユーザが最初にロ +グインした際に, ``authenticate`` メソッドでその処理を行うようにしてもよい +でしょう. + +以下に示すバックエンドの例では, ``settings.py`` ファイルに定義されたユーザ +名とパスワードに対して認証を行い,ユーザが最初に認証を行ったときに ``User`` +オブジェクトを生成します:: + + from django.conf import settings + from django.contrib.auth.models import User, check_password + + class SettingsBackend: + """ + Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD. + + Use the login name, and a hash of the password. For example: + + ADMIN_LOGIN = 'admin' + ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de' + """ + def authenticate(self, username=None, password=None): + login_valid = (settings.ADMIN_LOGIN == username) + pwd_valid = check_password(password, settings.ADMIN_PASSWORD) + if login_valid and pwd_valid: + try: + user = User.objects.get(username=username) + except User.DoesNotExist: + # Create a new user. Note that we can set password + # to anything, because it won't be checked; the password + # from settings.py will. + user = User(username=username, password='get from settings.py') + user.is_staff = True + user.is_superuser = True + user.save() + return user + return None + + def get_user(self, user_id): + try: + return User.objects.get(pk=user_id) + except User.DoesNotExist: + return None diff --git a/cache.txt b/cache.txt new file mode 100644 index 0000000..d81e486 --- /dev/null +++ b/cache.txt @@ -0,0 +1,612 @@ +================================= +Django のキャッシュフレームワーク +================================= + +:revision-up-to: 4805 (release 0.96) + +動的な Web サイトの根本的なトレードオフ要因とは,まさに動的であるということ +そのものです.ユーザがページをリクエストするたびに,サーバはデータベースへ +のクエリからテンプレートのレンダリングやビジネスロジックといった全ての計算 +を実行して,サイト訪問者が見るページを生成します.これは,処理のオーバヘッ +ドという観点から考えると,ファイルシステムからファイルを読み出すタイプの標 +準的なサーバ設計よりもはるかに高くつきます. + +ほとんどの Web アプリケーションでは,このオーバヘッドはたいしたものではあり +ません.ほとんどの Web アプリケーションは washingtonpost.com や +slashdot.org とは違って,小規模から中規模のサイトであり,トラフィックもそこ +そこにすぎません.しかし,中規模以上のサイトや高いトラフィックをさばかねば +ならないサイトでは,可能なかぎりオーバヘッドを削るのは基本です. + +そこでキャッシュが登場します. + +コンテンツのキャッシュとは,コストのかかる計算で,かつ一度計算したら再度計 +算する必要のないものの結果を保存することです.以下の疑似コードは,動的に生 +成されるWeb ページで,キャッシュがどのように動作するかを説明しています:: + + # ある URL に対し,キャッシュに該当するページがないか探す + given a URL, try finding that page in the cache + # キャッシュ内にページがある場合 + if the page is in the cache: + # キャッシュされたページを返す + return the cached page + else: + # ページを生成する + generate the page + # 生成されたページを (次のリクエスト用に) キャッシュに保存 + save the generated page in the cache (for next time) + # 生成されたページを返す. + return the generated page + +Django には堅牢なキャッシュシステムが付属しており,動的なページを保存して, +リクエストの度に最計算しなくてもよいようになっています.利便性のため, +Django には様々な粒度でのキャッシュを提供しており.特定のビューだけをキャッ +シュしたり,生成に時間を要する部分だけをキャッシュしたり,サイト全体をキャッ +シュしたりできます. + +Django は Squid (http://www.squid-cache.org/) のような「上流の」キャッシュ +や,ブラウザベースのキャッシュともうまく協調できます.こうした類のキャッシュ +は直接制御できませんが,サイトのどの部分をどのようにキャッシュすべきかを +(HTTP ヘッダを介して) ヒントとして与えられます. + +.. _Setting up the cache: + +キャッシュを立ち上げる +====================== + +キャッシュシステムを使うには,少し設定が必要です.例えば,キャッシュデータ +をどこに置くか,データベース上か,ファイルシステム上か,それともメモリ上か +を指定せねばなりません.これはキャッシュのパフォーマンスに影響する重要な決 +定です; そう,あるキャッシュ方式が別の方式より高速な場合もあるのです. + +キャッシュの選択は設定ファイルの ``CACHE_BACKEND`` 設定で行います. +CACHE_BACKEND に設定できる値を以下に示します. + +memcached +--------- + +Django で利用できるキャッシュの中でも断然高速で,もっとも高効率である +memcached は,完全なメモリベースのキャッシュフレームワークです. memcached +はもともと LiveJournal.com の高負荷を低減するために開発され,その後 Danga +Interactive でオープンソース化されました. memcached は Slashdot や +Wikipedia で使われており,データベースアクセスを低減して,サイトのパフォー +マンスを劇的に向上させます. + +memcached は http://danga.com/memcached/ から無料で入手できます. memcached +はデーモンとして動作し,指定された量の RAM の割り当てを受けます. memcached +の役割は,キャッシュ内に任意のデータを追加し,取り出したり削除したりするた +めのインタフェース,それも *超稲妻迅い* インタフェースを提供することにあり +ます.全てのデータは直接メモリ上に保存されるので,データベースやファイルシ +ステムの使用によるオーバヘッドがなくなります. + +memcached 本体のインストールの他に, memcached の Python バインディングをイ +ンストールする必要があります. Python バインディングは単一のモジュール +memcached.py で, ftp://ftp.tummy.com/pub/python-memcached/ から入手できま +す.この URL が有効でなくなっているなら, memcached のウェブサイト +(http://www.danga.com/memcached/) に行って, "Client API" セクションから +Python バインディングを入手してください. + +Django を memcached と組み合わせて使うには, ``CACHE_BACKEND`` を +``memcached://ip:port/`` に設定します. ``ip`` は memcached デーモンを動か +しているホストの IP アドレス, ``port`` はポート番号です. + +以下の例では, memcached をローカルホスト (127.0.0.1) のポート番号 11211 +で動かしています:: + + CACHE_BACKEND = 'memcached://127.0.0.1:11211/' + +memcached の素晴らしい点の一つは,複数のサーバ間でキャッシュを共有できると +いうことです.この機能を利用するには,全てのサーバアドレスをセミコロンで区 +切って ``CACHE_BACKEND`` に設定します.以下の例では, IP アドレスが +172.19.26.240 と 172.19.26.242 で,いずれもポート番号 11211 で動作している +memcached インスタンスでキャッシュを共有しています:: + + CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11211/' + +メモリベースのキャッシュには一つだけ短所があります: キャッシュデータはメモ +リ上に保存されるので,サーバクラッシュ時に失われることがあります.いうまで +もなく,メモリは永続的なデータ保存場所ではありません.ですから,データの保 +存場所を確保するのにメモリベースのキャッシュに依存してはなりません.実際に +は, Django のキャッシュバックエンドのいずれも永続的な記憶装置にはなりえま +せん -- キャッシュバックエンドは記憶装置ではなく,あくまでもキャッシュ用で +す -- ただ,メモリベースのキャッシュは特に一時性が高いため,ここで注意して +おきます. + +.. _Database caching: + +データベースを使ったキャッシュ +------------------------------ + +データベーステーブルをキャッシュバックエンドに使うには,まず以下のコマンド +を実行してデータベース上にキャッシュテーブルを作成します:: + + python manage.py createcachetable [cache_table_name] + +``[cache_table_name]`` は作成したいデータベーステーブルの名前です. (この名 +前は,現在データベースで既に使われていない有効なテーブル名なら何でも構いま +せん.) このコマンドはデータベース中に Django のデータベースキャッシュシス +テム向けの適切な形式のテーブルを生成します. + +キャッシュ用のテーブルを作成したら, ``CACHE_BACKEND`` 設定を +``"db://tablename/"`` にします. ``tablename`` はキャッシュ用テーブルの名前 +です.以下の例では,キャッシュテーブル名を ``my_cache_table`` にしています:: + + CACHE_BACKEND = 'db://my_cache_table' + +データベースのキャッシュがうまく働くのは,高速でインデクス構築のよくできた +データベースサーバを使っている場合です. + +.. _Filesystem caching: + +ファイルシステムを使ったキャッシュ +---------------------------------- + +ファイルシステム上にキャッシュしたい内容を置くには, ``CACHE_BACKEND`` に +``"file://"`` キャッシュ形式を指定します.例えば,キャッシュデータを +``/var/tmp/django_cache`` に置きたいなら,以下のように設定します:: + + CACHE_BACKEND = 'file:///var/tmp/django_cache' + +先頭にスラッシュが 3 つ連なっていることに注意して下さい.最初の 2 つのスラッ +シュや ``file://`` の一部で,最後のスラッシュはディレクトリパス +``/var/tmp/django_cache`` の最初の文字です. + +ディレクトリパスは常に絶対パス指定.すなわち,ファイルシステムのルートから +始まるパス名を指定せねばなりません.パスの末尾にスラッシュを追加するかどう +かは問題にはなりません. + +この設定の指し示すパスが実在し, Web サーバを動かしているシステムユーザから +読み書き可能であるようにしてください.上の例でいうなら,サーバを ``apache`` +というユーザで動かしている場合, ``/var/tmp/django_cache`` ディレクトリが実 +在して, ``apache`` によって読み書き可能かどうかをチェックしてください. + +.. _Local-memory caching: + +ローカルメモリ上のキャッシュ +---------------------------- + +メモリを使ったキャッシュの恩恵を受けたい一方で, memcached を動かせない状況 +にある場合には,ローカルメモリを使ったキャッシュバックエンドを検討してみて +ください.このキャッシュはマルチプロセスセーフかつスレッドセーフです.使う +には, ``CACHE_BACKEND`` に ``"locmem:///"`` と指定します. +以下のようにして使います:: + + CACHE_BACKEND = 'locmem:///' + +.. _Simple caching (for development): + +簡単なキャッシュ (開発用) +------------------------- + +``"simple:///"`` を指定すると,簡単な単一プロセス用のメモリキャッシュを使え +ます.このキャッシュは単にデータをプロセス内に保存するだけなので,開発やテ +スト環境だけで使うべきです.以下のようにして使います:: + + CACHE_BACKEND = 'simple:///' + +.. _Dummy caching (for development): + +ダミーキャッシュ (開発用) +------------------------- + +最後に, Django には「ダミーの」キャッシュが付いてきます.このキャッシュは +実際にはなにもしません -- 単に何もしないキャッシュインタフェースを実装して +いるだけです. + +ダミーキャッシュが便利になるのは,そこかしこで様々なキャッシュを使っている +ような実運用サイトを構築していて,開発/テスト環境ではキャッシュを行いたく +ないような場合です.こうした状況では,開発環境向けの設定ファイルでは +``CACHE_BACKEND`` を ``"dummy:///"`` にしておきます.その結果,開発環境で +はキャッシュを行わなくなります. + +.. _CACHE_BACKEND arguments: + +CACHE_BACKEND の引数 +-------------------- + +これらのキャッシュは全て引数をとれます.引数はクエリ文字列の形式をとります. +使える引数は以下の通りです: + + timeout + デフォルトのタイムアウトで,単位は秒です.デフォルト値は 5 分 (300 + 秒) に設定されています. + + max_entries + simple および database バックエンド用の引数で,キャッシュの消去を + 行わずに残しておけるエントリの最大数です.デフォルト値は 300 です. + + cull_percentage + キャッシュ内のエントリ数が max_entries を越えたときに淘汰されるエン + トリの割合です.実際の百分率は 1/cull_percentage で決定されます.従っ + て,キャッシュエントリ数が max_entries を越えたときに全体の 1/3 の + エントリを淘汰したければ, ``cull_percentage=3`` と設定します. + + cull_percentage に 0 を指定すると,キャッシュエントリ数が + max_entries に到達した時に全てのキャッシュエントリを廃棄します. + この設定は,キャッシュミスの増加と引き換えに,淘汰処理を *劇的に* + 高速化します. + +以下の例では,タイムアウトは ``60`` に設定されています:: + + CACHE_BACKEND = "memcached://127.0.0.1:11211/?timeout=60" + +不正な引数や引数値は暗黙のうちに無視されます. + +In this example, ``timeout`` is ``30`` and ``max_entries`` is ``400``:: + + CACHE_BACKEND = "memcached://127.0.0.1:11211/?timeout=30&max_entries=400" + + +.. _The per-site cache: + + +サイト単位のキャッシュ +====================== + +キャッシュの立ち上げ後,最も簡単なキャッシュの用法はサイト全体のキャッシュ +です.設定は設定ファイルの ``MIDDLEWARE_CLASSES`` に +``'django.middleware.cache.CacheMiddleware'`` を追加するだけです.例えば以 +下のようにします:: + + MIDDLEWARE_CLASSES = ( + 'django.middleware.cache.CacheMiddleware', + 'django.middleware.common.CommonMiddleware', + ) + +(``MIDDLEWARE_CLASSES`` の順番は重要です.後述の「MIDDLEWARE_CLASSES の順番」 +を参照してください) + +次に,以下の必須の設定を Django 設定ファイルに追加します: + +* ``CACHE_MIDDLEWARE_SECONDS`` -- 各ページのキャッシュ時間を秒単位で指定し + ます. +* ``CACHE_MIDDLEWARE_KEY_PREFIX`` -- 同じ Django の下にある複数のサイト間で + キャッシュを共有する場合,この値をサイトの名前にするか, Django インスタ + ンスごとに固有の文字列にして,キャッシュのキー衝突を防ぎます.キー衝突を + 気にする必要がない場合は空文字列を設定します. + +キャッシュミドルウェアは GET または POST パラメタをもたない全てのページを +キャッシュします.オプションとして, ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` +設定を ``True`` にすると,匿名のリクエスト (すなわちログインユーザ以外から +のリクエスト) だけをキャッシュするようになります.これは (Django の admin +インタフェースを含む) ユーザ固有のページに対するキャッシュを無効化する際に +便利です.ただし, ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` を使う場合は,必ず +``AuthenticationMiddleware`` を有効にして, ``MIDDLEWARE_CLASSES`` の中で +``AuthenticationMiddleware`` が ``CacheMiddleware`` よりも前にくるようにしてください. + +加えて, ``CacheMiddleware`` は自動的に以下のヘッダを ``HttpResponse`` に追 +加します: + +* 「新鮮な」(キャッシュされていない) ページをリクエストされた場合には, + ``Last-Modified`` ヘッダを現在の date/time に設定します. +* ``Expires`` ヘッダを現在時刻と ``CACHE_MIDDLEWARE_SECONDS`` を加算した + 値に設定します. +* ``CACHE_MIDDLEWARE_SECONDS`` に基づき, ``Cache-Control`` ヘッダにページ + の最長寿命を設定します. + +ミドルウェアの詳細は `ミドルウェアのドキュメント`_ を参照してください. + +.. _`ミドルウェアのドキュメント`: ../middleware/ +.. _`middleware documentation`: ../middleware/ + +.. _The per-view cache: + +ビュー単位のキャッシュ +====================== + +キャッシュフレームワークをもう少し低い粒度で使うには,個々のビューの出力を +キャッシュします. ``django.views.decorators.cache`` には関数デコレータ +``cache_page`` があり,自動的にビューからの応答をキャッシュします. +使い方は簡単です:: + + from django.views.decorators.cache import cache_page + + def slashdot_this(request): + ... + + slashdot_this = cache_page(slashdot_this, 60 * 15) + +Python 2.4 のデコレータ構文を使うと以下のようになります:: + + @cache_page(60 * 15) + def slashdot_this(request): + ... + +``cache_page`` は単一の引数をとります.これはキャッシュのタイムアウトを秒で +表したものです.上の例では, ``slashdot_this()`` の出力結果は 15 分間キャッ +シュされます. + +.. _The low-level cache API: + +低水準のキャッシュ API +====================== + +ときに,レンダリングされたページ全体のキャッシュが十分でないことがあります. +例えば,集約的なデータベースのクエリだけをキャッシュすればよいと考えるかも +しれません.このような場合のために,低水準のキャッシュ API を使って,オブジェ +クトを好きな粒度でキャッシュに保存できます. + +キャッシュ API は簡単なものです.キャッシュを表現するモジュールである +``django.core.cache`` は ``CACHE_BACKEND`` 設定に基づいて生成された +``cache`` オブジェクトを公開しています:: + + >>> from django.core.cache import cache + +基本となるインタフェースは ``set(key, value, timeout_seconds)`` と +``get(key)`` です:: + + >>> cache.set('my_key', 'hello, world!', 30) + >>> cache.get('my_key') + 'hello, world!' + +``timeout_seconds`` 引数はオプションで,デフォルト値は ``CACHE_BACKEND`` 設 +定の timeout 引数の値になります (これについては上記を参照してください). + +オブジェクトがキャッシュの中になければ, ``cache.get()`` は ``None`` を返し +ます:: + + >>> cache.get('some_other_key') + None + + # Wait 30 seconds for 'my_key' to expire... + + >>> cache.get('my_key') + None + +get() には ``default`` 引数を指定できます:: + + >>> cache.get('my_key', 'has_expired') + 'has_expired' + +キャッシュを一度しかアクセスしない ``get_many()`` インタフェースもあります. +``get_many()`` は指定した全てのキーのうち,キャッシュ内に実在する (そして期 +限切れでない) ものの入った辞書を返します:: + + >>> cache.set('a', 1) + >>> cache.set('b', 2) + >>> cache.set('c', 3) + + >>> cache.get_many(['a', 'b', 'c']) + {'a': 1, 'b': 2, 'c': 3} + +最後に,明示的なキーの削除は ``delete()`` で行えます.これは特定のオブジェ +クトに対するキャッシュを消去する簡単な方法です:: + + >>> cache.delete('a') + +これだけです.キャッシュにはほとんど制限がありません: 安全に pickle 化でき +るオブジェクトならなんでもキャッシュできます.ただし,キーは文字列でなけれ +ばなりません. + +.. _Upstream caches: + +上流キャッシュ +============== + +ここまでは, *自分の* データに対するキャッシュについて説明してきました.し +かし, Web 開発にはもう一つのタイプのキャッシュが関係も関係してきます.それ +は 「上流 (upstream)」のキャッシュ機構で行われているキャッシュです.上流の +キャッシュは,ユーザのリクエストが Web サイトに到達する前ですらページのキャッ +シュを行います. + +上流キャッシュの例をいくつか示します: + + * ISP が特定のページをキャッシュしている場合, somedomain.com のページ + をリクエストしても, ISP はキャッシュページを返し, somedomain.com に + アクセスしないかもしれません. + + * ページをキャッシュしてパフォーマンスを向上させるために, Django Web + サイトを Squid Web プロキシ (http://www.squid-cache.org/) の背後に置 + けます.この場合,リクエストはまず Squid でさばかれ,必要な時にのみア + プリケーションに渡されるようになります. + + * Web ブラウザもページをキャッシュします. Web ページが適切なヘッダを送 + 信すると,ブラウザは以後の同じページへのリクエストにはローカルの (キャッ + シュされた) コピーを使うようになります. + +上流のキャッシュは効率を高める良い方法ではありますが,危険もはらんでいます: +多くの Web ページのコンテンツは認証に応じて異なる内容になります.また,その +他の変数も入ります.キャッシュシステムが純粋に URL だけに基づいてページを +盲目的に保存してしまうと,同じページを後から見た訪問者に対して正しくない情 +報や機密の情報を晒してしまいます. + +例えば, Web ベースの e-mail システムを操作しているとしましょう."inbox" +ページのコンテンツはいうまでもなくログインしているユーザ固有のものです. +ある ISP が盲目的にサイトをキャッシュしてしまうと,その ISP を経由して最初 +にログインしたユーザは自分の inbox ページをキャッシュしてしまい,以降に +そのサイトを訪れたユーザが閲覧できるようになってしまいます.これはよろしく +ありません. + +幸運にも, HTTP にはこうした問題に対する解決策があります.すなわち,キャッ +シュ機構に指定の変数に基づいてコンテンツのキャッシュを行うよう指示したり, +キャッシュメカニズムが特定のページをキャッシュしないように指示したりする +一連の HTTP ヘッダがあるのです. + +.. _Using Vary headers: + +Vary ヘッダを使う +================= + +こうしたヘッダの一つに ``Vary`` があります. ``Vary`` ヘッダは,キャッシュ +機構がキャッシュキーを生成するときに,どのリクエストヘッダを考慮すべきかを +定義しています.例えば, Web ページのコンテンツが言語設定に依存している場合, +ページは「言語によって変化 (vary)」します. + +デフォルトでは, Django のキャッシュシステムはキャッシュキーをリクエストの +パス部分,例えば ``"/stories/2005/jun/23/bank_robbed/"`` を使って生成します. +これでは,クッキーや言語設定のようなユーザエージェント間の違いにかかわらず, +同じ URL を指すリクエストは全て同じバージョンのキャッシュを使うことになって +しまいます. + +そこで ``Vary`` が登場します. + +Django 下のページが,クッキーや言語,ユーザエージェントといったリクエストヘッ +ダ上の違いに基づいて,違った内容を出力する場合, ``Vary`` ヘッダを使って, +ページ出力が何に依存しているかをキャッシュメカニズムに教える必要があります. + +Django でこれを行うには,以下のような便宜用のビュー関数デコレータ, +``vary_on_headers`` を使います:: + + from django.views.decorators.vary import vary_on_headers + + # Python 2.3 syntax. + def my_view(request): + ... + my_view = vary_on_headers(my_view, 'User-Agent') + + # Python 2.4 decorator syntax. + @vary_on_headers('User-Agent') + def my_view(request): + ... + +上の場合では, (Django 自体のキャッシュミドルウェアのような) キャッシュメカ +ニズムは個々のユーザエージェント固有の別のバージョンをキャッシュします. + +``Vary`` ヘッダを (``response['Vary'] = 'user-agent'`` のような操作で) 手動 +で変更せずに, ``vary_on_headers`` デコレータを使う利点は,デコレータが (す +でに存在するかもしれない) ``Vary`` ヘッダをスクラッチから作るのではなく,き +ちんと追加処理を行う点にあります. + +``vary_on_headers()`` には複数のヘッダを渡せます:: + + @vary_on_headers('User-Agent', 'Cookie') + def my_view(request): + ... + +クッキーによるコンテンツの変更はよくあることなので, ``vary_on_cookie`` +デコレータも用意されています.従って,以下の二つのビューは同じ振舞いをします:: + + @vary_on_cookie + def my_view(request): + ... + + @vary_on_headers('Cookie') + def my_view(request): + ... + +``vary_on_headers`` に渡すヘッダは大小文字を区別しないので注意してください. +``"User-Agent"`` は ``"user-agent"`` と同じです. + +ヘルパー関数 ``django.utils.cache.patch_vary_headers()`` も直接使えます:: + + from django.utils.cache import patch_vary_headers + def my_view(request): + ... + response = render_to_response('template_name', context) + patch_vary_headers(response, ['Cookie']) + return response + +``patch_vary_headers`` は第一引数に ``HttpResponse`` インスタンスをとり,ヘッ +ダ名のリストまたはタプルを第二引数にとります. + +Vary ヘッダの詳細は `公式の Vary の仕様`_ を参照してください. + +.. _`公式の Vary の仕様`: + http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44 + +.. _`Controlling cache: Using other headers`: + +Vary ヘッダ以外のヘッダを使ったキャッシュ制御 +============================================= + +キャッシュの利用で起きるもう一つの問題は,データのプライバシーと,カスケー +ド接続したキャッシュのどこにデータを保存すべきかという疑問です. + +通常,ユーザの目に触れるのは二種類のキャッシュ,すなわち自分のブラウザのキャッ +シュ (プライベートのキャッシュ) と,ページプロバイダ側のキャッシュ (公開の +キャッシュ) です.公開のキャッシュは複数のユーザによって利用されており,別 +のユーザがその内容を制御することもあります.これは,注意の必要なデータを扱 +う際には問題になります: 例えば,銀行のアカウント番号を公開キャッシュに保存 +して欲しくはないでしょう.つまり, Web アプリケーションにはどのデータがプラ +イベートで,どのデータが公開なのかを区別する方法が必要なのです. + +この問題の解決策は,ページキャッシュが「プライベート」であると示すことです. +Django では, ``cache_control`` ビューデコレータを使ってこれを実現します. +例えば:: + + from django.views.decorators.cache import cache_control + @cache_control(private=True) + def my_view(request): + ... + +このデコレータは,適切な HTTP ヘッダが送信されるように背後で気を配ります. + +他にもキャッシュパラメタを操作する方法がいくつかあります.例えば, HTTP を +使うアプリケーションは以下のような操作を行えます: + + * ページの最大キャッシュ回数を定義できます. + * キャッシュされているコンテンツの新たなバージョンがないか常に調べ,変 + 更がないときに限ってキャッシュを送信するように設定できます (キャッシュ + によっては,サーバ上のページが変更されていても,単にキャッシュコピー + の有効期限が切れていないという理由でキャッシュされた内容を配信するこ + とがあります). + + +Django では,ビュー関数デコレータの ``cache_control`` を使って,キャッシュ +パラメタを設定します.以下の例では, ``cache_control`` を使って,アクセス +ごとにコンテンツの再検証を行い,キャッシュされたバージョンの最大保存期限を +3600 秒に設定しています:: + + from django.views.decorators.cache import cache_control + @cache_control(must_revalidate=True, max_age=3600) + def my_view(request): + ... + +有効な ``Cache-Control`` HTTP ディレクティブは全て ``cache_control()`` に +使えます.利用できるディレクティブを示します: + + * ``public=True`` + * ``private=True`` + * ``no_cache=True`` + * ``no_transform=True`` + * ``must_revalidate=True`` + * ``proxy_revalidate=True`` + * ``max_age=num_seconds`` + * ``s_maxage=num_seconds`` + +Cache-Control HTTP ディレクティブの説明は `Cache-Control の仕様`_ を参照し +てください. + +(キャッシュミドルウェアは常にキャッシュヘッダの最長寿命 (max-age) を +``CACHE_MIDDLEWARE_SETTINGS`` の設定値に設定するので注意してください.カス +タムの ``max_age`` を ``cache_control`` デコレータで使うと,デコレータの設 +定が優先され,ヘッダの値は正しくマージされます.) + +.. _`Cache-Control の仕様`: + http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 + +.. _Other optimizations: + +その他の最適化 +============== + +Django には,アプリケーションのパフォーマンスを最適化する上で役立つミドルウェ +アが他にもいくつかあります: + + * ``django.middleware.http.ConditionalGetMiddleware`` を使うと,条件付 + き GET をサポートできるようになり, ``ETag`` および ``Last-Modified`` + ヘッダを使えるようになります. + + * ``django.middleware.gzip.GZipMiddleware`` は gzip 圧縮を扱えるブラウ + ザ (最近のほとんどのブラウザがそうです) に対して,コンテンツを gzip + で圧縮します. + + +.. _Order of MIDDLEWARE_CLASSES: + +MIDDLEWARE_CLASSES の順番 +========================= + +``CacheMiddleware`` を使っている場合, ``MIDDLEWARE_CLASSES`` 中の正しい場 +所に ``CacheMiddleware`` の設定を入れておくことが重要です.というのも,キャッ +シュミドルウェアはどのヘッダがキャッシュストレージを変更するのかを知ってお +く必要があるからです. + +ミドルウェアは,可能なときは常に ``Vary`` レスポンスヘッダに何らかのデータ +を追加します. + +``Vary`` ヘッダに何かを追加する可能性のあるミドルウェアよりも後ろに +``CacheMiddleWare`` を置くようにしてください.例えば以下のミドルウェアは +``Vary`` ヘッダに手を加えます: + + * ``SessionMiddleware`` は ``Cookie`` を追加します. + * ``GZipMiddleware`` は ``Accept-Encoding`` を追加します. diff --git a/contributing.txt b/contributing.txt new file mode 100644 index 0000000..524988b --- /dev/null +++ b/contributing.txt @@ -0,0 +1,737 @@ +=================================== +Django プロジェクトに協力するために +=================================== + +:revision-up-to: 4805 (release 0.96) + +Django を *使う* のを楽しいと思ってもらえたなら, *使い続ける* 前にすこし待っ +てください.私達は多大な情熱をかけて,ユーザがコミュニティのメンバに貢献で +きるよう手助けしています.Django の開発を手伝うにはいくつもの方法があります: + + + * Django について blog を書きましょう.私達は知っている限りの全ての + Django 関係の blog を `コミュニティのページ`_ で配信しています.この + ページに登録したい blog があるなら jacob@jacobian.org に連絡してくだ + さい. + + * バグ報告や機能に関する要望を `チケットトラッカ`_ に提出しましょう. + 私達が望んでいるバグ報告の提出方法の詳細は `バグの報告`_ を読んで下さい. + + * 新たな機能を追加したり従来の機能を修正するパッチを提出しましょう. + パッチの提出方法は `パッチの提出`_ を参照してください. + + * `django-developers`_ メーリングリストに参加して, Django をよりよくす + るためのアイデアを皆で共有しましょう.どんな提案でも歓迎します.ただ + し私達は後ろだてになるコードがないスケールの大きな話には懐疑的です. + + * 他のユーザが提出したパッチのトリアージ (選別) を行います.トリアージ + の手順については,後述の `チケットのトリアージ <#ticket-triage>`_ を + 参照してください. + +Django 開発コミュニティに参加するのに必要な知識はこれだけです.このドキュメ +ントの残りの部分では,開発コミュニティがどのようになっていて,どうやってバ +グを処理しているかについて詳しく説明し,メーリングリストやその他こまごまと +した注意点について記述しています. + +.. _Reporting bugs: + +バグの報告 +============== + +上手に書かれたバグ報告は *信じられないくらい* 助けになります.とはいえ,バ +グ追跡システムでの作業はかなりのオーバヘッドを要するので,チケットトラッカ +をできるだけ有意義に使うよう協力していただけると助かります.特に: + + * **必ず** FAQ_ を読んで,自分の抱えている問題が既知のものでないか探し + て下さい. + + * **必ず** `トラッカを検索`_ して,自分の抱えている問題がファイルされて + いないか探して下さい. + + * **必ず** *最初に* `django-users`_ で質問して,自分の考えていることが + バグだということを確認してください. + + * **必ず** 完結した,再現可能な,的確なバグ報告を書いて下さい.完全なコー + ド断片やテストセットなど,可能な限り多くの情報を含めて下さい.問題に + 対する詳細かつ明瞭な説明と,問題を再現するための手順を含めてください. + 小さなテストケースでバグを再現できれば最良のバグ報告になります. + + * **決して** サポート質問にチケットシステムを **使わないで下さい.** 質 + 問は `django-users`_ リストや `#django`_ IRC チャネルでお願いします. + + * **決して** スケールの大きな機能の提案にチケットシステムを + **使わないで下さい.** Django のコアに関わる大きな変更は, + 取り掛かる前に必ず `django-developers`_ リストで議論します. + + * **決して** "wontfix" にマークされた問題を + **開き直さないで下さい.** "wontfix" マークは決定事項であり,この問題 + についてはこれ以上修正できないか,修正する予定はないのです.納得でき + なければ, `django-developers`_ で質問してください. + + * **決して** 長い議論をチケットシステムで **行わないで下さい.** チケッ + トシステムでは議論内容がじきに失われてしまうからです.チケットの内容 + について議論になりそうなときは `django-developers`_ に場所を移して下 + さい. + +.. _Reporting security issues: + +セキュリティ問題の報告 +========================= + +セキュリティ問題の報告は security@djangoproject.com にお願いします.このメー +リングリスト経験豊かで信頼できる Django 開発者だけが購読でき,アーカイブは +非公開になっています. + +Django に脆弱性が発見された場合,私達は以下のように行動します: + + * 報告者に対して,報告を受けとったことと,脆弱性がまもなく修正されるこ + とを知らせます.修正までのおおまかなタイムラインを示し,報告者に対し + て,アナウンスを行うまでにどのくらいの間この問題を秘密にしておけるか + 問い合わせます. + + * 現在のバージョンと,二つ前までのリリースに対するパッチを含む修正版の + 開発に必要な期間,他の全ての開発を停止します. + + * 脆弱性と修正版をアナウンスするする日取りを決めます. パッチを適用する + 側と脆弱性を不正利用する側の間の「軍拡競争」を抑えるため,私達はセキュ + リティ問題を即座にアナウンスしません. + + * 影響を受けるバージョンの Django を使っているユーザのうち,私達が把握 + している人全員に事前に通知します.この通知は個人宛の電子メールで行わ + れます.メールには脆弱性に関するドキュメントと該当パッチへのリンク, + そしてこの脆弱性を公式の公開日まで秘密にしておくよう要請する文が入っ + ています. + + * あらかじめ決めておいた日取りに基づいて,脆弱性と修正版を公開し,アナ + ウンスします.通常は新たなバージョンの Django リリースを意味しますが, + 場合によっては現在のリリースに対する単なるパッチになります. + +.. _Submitting patches: + +パッチの提出 +================== + +Django のコードに対するパッチはつねに大歓迎です.実際,パッチつきのバグ報告 +は,パッチのないものよりも *はるかに* 素早く修正されます. + +.. _Patch style: + +パッチ形式 +----------- + + * Django の `コーディングスタイル`_ に従っているか確認してください. + + * ``svn diff`` コマンドの返す書式のパッチを提出してください.ただし,コー + ドよりも英語で変更点を説明した方がはるかに分かりやすい場合は例外です. + 例えばインデントはよくある例です.というのも,コードの違いがインデン + トでしかない場合,パッチを読むのはとても大変だからです. + + * `チケットトラッカ`_ で, "attach file" ボタンを使ってチケットにパッチ + を添付してください.一行のパッチでないかぎり,チケットの説明やコメン + トの中にパッチを *入れないで* 下さい. + + * パッチファイルの名前には ``.diff`` 拡張子をつけて下さい.そうすること + で,チケットトラッカは構文のハイライト強調を正しく行うので助かります. + + * チケットの詳細情報欄にある「パッチ付き」("Has patch") ボックスにチェッ + クを入れてください.チケットがパッチつきであることが分かりやすくなり, + チケットシステムがそのチケットを `パッチつきのチケットのリスト`_ に追 + 加してくれます. + + * 問題を解決したり機能を追加するためのコードはパッチの重要な部分ですが, + それだけではいけません.よいパッチというものには必ず回帰テストが付属 + していて,問題が解決されたことを検証できる (そして将来同様の問題が再 + 発しないようにできる) ものです. + + * パッチ中のコードが新たな機能や既存の機能に対する変更をもたらす場合, + パッチにはドキュメントも含めてください. + +.. _Non-trivial patches: + +重要パッチ +---------- + +「重要 (non-trivial)」パッチとは,単なるバグフィクスに留まらず,Django に +新たな機能をもたらし,何らかの設計上の判断を迫るようなパッチです. + +重要パッチを提出する場合には,その問題について `django-developers`_ で議論 +済みであるという証明を含めてください.自分のパッチが重要パッチかどうか判断 +しかねる場合には問い合わせてください. + +.. _Ticket triage: + +チケットのトリアージ +==================== + +残念ながら, `チケットトラッカ`_ に届くバグ報告全てが,上に述べた +`チケットの要件 <#reporting-bugs>`_ を満たしているわけではありません. +パッチの添付されたチケットもたくさんありますが,それら全てが +`よいパッチ <#patch-style>`_ の要件を満たしているわけでもありません. + +こうした状況の打開を手助けする一つの方法に,他のユーザが報告したバグのトリ +アージ (選別) 作業があります.この作業には献身的なボランティア 2 名が常時携 +わっていますが,手助けをしてくれる人は常に歓迎です. + +トリアージ作業のワークフローの大半は,チケットの「トリアージ段階 (triage +stage)」というフィールドに関わる作業です.このステージとは,あるチケットが +ライフサイクルのどの段階にあるかを示す指標です.ステージフラグやその他のフ +ラグによって,誰のどんなチケットが処理待ちになっているかがわかります. + +百聞は一見にしかずですから,例を挙げて説明しましょう: + +.. image:: http://media.djangoproject.com/img/doc/djangotickets.png + :height: 451 + :width: 590 + :alt: Django のチケットワークフロー図 + +まず,チケット処理に関わる人たちには 2 種類の役割があります: + + * コア開発者: コミット権限を持ち,コードに関する決定や,大部分のコード + 作成を行う人です. + + * トリアージ作業者: 個々チケットを追跡して,チケットが正しく分別された + 状態になるよう作業する人です. + +次に,トリアージ作業には以下の 4 つのステージがあります: + + 1. チケットは「未レビュー(unreviewed)」の状態からスタートします.この状 + 態のチケットはまだトリアージ作業者によって検査されておらず,トリアー + ジ作業が開始されていません. + + 2. 「設計判断待ち(design decision needed)」は,「このコンセプトには設計 + 上の判断が必要」であり,チケットのコメント欄か, django-developers + 上で議論すべきであることを示しています. + + 3. チケットの内容に従った修正が受け入れられた場合,「承認 (accepted)」 + ステージに移行します.このステージは全ての作業が終わった状態です. + + 4. チケットにパッチが関連づけられている場合 (下記参照),トリアージ作業 + 者はパッチをレビューします.パッチの内容が完璧なら,「チェックイン可 + (ready for checkin)」にマークされ,コア開発者にパッチをレビューし + てチェックすべきであることを知らせます. + +ワークフローにはもう 1 つ,一連のフラグがあります.フラグは各チケットを +「チェックイン可」にするために必要な条件のうち,何が満たされていて何が必要 +かを示します: + + 「パッチあり (has patch)」 + チケットに `パッチ <#patch_style>`_ が添付されていることを示します. + このフラグのついたパッチはレビューされ,条件を満たした「よいパッチ」 + であるかどうか調べられます. + + 「ドキュメント不足 (needs documentation)」 + パッチつきのチケットに対して,ドキュメントが必要であることを示しま + す.コードベースに修正をチェックインする条件として,完全なドキュメ + ントが必要です. + + 「テスト不足 (needs tests)」 + パッチに単位テストが必要であることを示します.上ど同様,条件として + 有効なパッチが必要です. + + 「パッチに改良の余地あり (patch needs improvement)」 + チケットにパッチが *付属している* が,チェックインするには修正の余 + 地があることを示します.パッチが古くてきれいに当てられなくなってし + まっている場合や,コードがコーディング基準に従っていないことを示し + ます. + +チケットは色々な形で解決されます: + + 「修正済み (fixed)」 + パッチが Django に取り込まれ,問題が解決されると,コア開発者はチケッ + トを fixed にマークします. + + 「無効 (invalid)」 + チケットの内容が不正確だったり,何らかの手違いで作成されたチケット + には invalid マークをつけます. + + 「修正の予定なし (wontfix)」 + 修正要求を Django に取り込むのは不適切であると判断した場合,コア開 + 発者はチケットを wondfix にマークします. wontfix へのマークは, + 通常は ``django-developer`` メーリングリストでの議論の末に選択され + ることなので,気になる議論があったらぜひ参加してください. + + 「他のチケットと重複 (duplicate)」 + 他のチケットで同じ問題がカバーされている場合にはチケットを + duplicate にマークします.重複したチケットをクローズして問題解決の + ための議論を 1 箇所にまとめ,話を進めやすくするためです. + + 「再現不能 (worksforme)」 + トリアージ作業チームがチケットに記載されているバグを再現できなかっ + た場合,チケットを worksforme にマークします. + +あるチケットが明らかに誤ってクローズされた -- クローズされたチケットで提起 +されている問題が依然として生じている場合や,別の問題が生じた場合,あるいは +トリアージ作業でミスが起きている -- 場合には,そのチケットを再度開いて +(reopen),その理由を記載してください.また,コア開発者が "wontfix" にマーク +したチケットを reopen しないでください. + + +.. _required details: `Reporting bugs`_ +.. _good patch: `Patch style`_ +.. _patch: `Submitting patches`_ + +.. _Submitting and maintaining translations: + +翻訳の提出と維持 +================ + +admin サイトやバリデータのエラーメッセージなど,Django は様々な部分で国際化 +されており,ユーザの言語設定に従って様々なテキストを表示します. + +翻訳カタログは世界中の Django ユーザによる貢献でできています.間違った翻訳 +や,まだ翻訳存在しない言語に新たな翻訳を追加したい場合は以下のようにします: + + * `Django i18n メーリングリスト`_ に参加して自己紹介してください. + * `i18n のドキュメント` に従って翻訳を作成し,提出してください. + +.. _`Django i18n メーリングリスト`: http://groups.google.com/group/django-i18n/ +.. _`i18n のドキュメント`: ../i18n/ + +.. _Coding style: + +コーディングスタイル +==================== + +コードを書いて Django に取り込みたいなら,以下のコーディング標準に従って下 +さい: + + * 特に指定のない限り `PEP 8`_ に従って下さい. + + * インデントにはスペース 4 つを使います. + + * 変数名,関数名,メソッド名には camelCase ではなくアンダースコアを使っ + て下さい (たとえば ``poll.getUniqueVoters`` ではなく + ``poll.get_unique_voters()``). + + * クラス名 (やクラスを返すファクトリ関数) には ``InitialCaps`` を使って + ください. + + * 国際化の必要な全ての文字列をマークしておいてください.詳しくは + `i18n ドキュメント`_ を参照してください. + + * Django テンプレートコード内では,波括弧とタグコンテンツの間に 1 個 (1 + 個だけ) スペースをいれて下さい. + + [正]:: + + {{ foo }} + + [誤]:: + + {{foo}} + + + * Django のビューを書くときには,最初のパラメタは必ず ``request`` とい + う名前にしてください. + + [正]:: + + def my_view(request, foo): + # ... + + [誤]:: + + def my_view(req, foo): + # ... + + * コード中に自分の名前を埋め込まないでください.Django プロジェクトでは, + コードの開発者や貢献者の名前がコード中に散逸しないようにするため, + ``AUTHORS`` ファイルにまとめて記載するというポリシを採用しています. + ほんのちょっとした変更でないかぎり,ご自分のパッチに ``AUTHORS`` への + 変更を加えて頂いてもかまいません. + +.. _Committing code: + +コードの commit +=============== + +Django の Subversion リポジトリにコードをコミットする場合には以下のガイドラ +インに従って下さい: + + * 中規模から大規模な変更 (「中規模から大規模」の判断は各自に任せます) + の際には,変更前に `django-developers`_ メーリングリストに相談を持ち + 込んで下さい. + + `django-developers`_ に持ち込んだ話題に対して返事がなかった場合,自分 + のアイデアが素晴らしく,すぐにでも実装すべきだと皆が思ったため誰も何 + も言わないのだと勘違いしないでください. Django の開発指揮者はメーリ + ングリストの議論にすぐに割ける時間を持ち合わせていないので,返事には + 数日待たねばならない場合もあるのです. + + * 詳しいコミットメッセージを過去形で書いて下さい.現在形を使ってはなり + ません. + + * 良い例: "Fixed Unicode bug in RSS API." + * 悪い例: "Fixes Unicode bug in RSS API." + * 悪い例: "Fixing Unicode bug in RSS API." + + * ブランチにコミットする場合,コミットメッセージの先頭にブランチ名を付 + けて下さい.例えば "magic-removal: Added support for mind reading." + のようにします. + + * 意味のある変更のまとまりであるかぎり,できるだけ細かい変更に分けてコ + ミットしてください.つまり,たまに大きなコミットをするのではなく,小 + さなコミットを頻繁に行うようにしてください.例えば,機能 X を実装して + いて,その機能の実現にライブラリ Y の修正が必要なら,まず Y の修正を + コミットして,次に X を別にコミットしてください.これだけで, Django + のコア開発者全員が変更を追うための *大きな* 助けになります. + + * コミットによって Django `チケットトラッカ`_ の何らかのチケットをクロー + ズする場合,コミットメッセージの先頭に "Fixed #abc" というメッセージ + を入れて下さい. "abc" はコミットによって修正されるチケットの番号です. + 例えば "Fixed # 123 -- Added support for foo" のようにします.私達は + Subversion と Trac を結びつけているので,この形式のメッセージを使って + commit した場合,関連するチケットを自動的にクローズし,完全なコミット + メッセージをコメントとしてチケットに追加します. + + コミットによってブランチのチケットをクローズする場合,ブランチ名を先 + にもってきます.例えば + "magic-removal: Fixed #123 -- Added whizbang feature." のようにします. + + ちなみに,この機能は `Trac の post-commit フック`_ で実現しています. + .. _Trac post-commit hook: http://trac.edgewall.org/browser/trunk/contrib/trac-post-commit-hook + .. _`Trac の post-commit フック`: http://trac.edgewall.org/browser/trunk/contrib/trac-post-commit-hook + + + * コミットメッセージで Django `チケットトラッカ`_ の何らかのチケットを + 参照し,かつチケットを *閉じない* 場合, "Refs #abc" というフレーズを + 入れて下さい. "abc" はコミットで参照しているチケットの番号です.私達 + は Subversion と Trac を結びつけているので,この形式のメッセージを使っ + て commit した場合,関連するチケットに完全なコミットメッセージをコメ + ントとして追加します. + +.. _Unit tests: + +単体テストの作成 +==================== + +Django には独自のテストスイートが付属しています.テストは tarball 内の +``test`` ディレクトリ下にあります.ポリシとして,常に全てのテストがパスする +ようにしています. + +テストでは以下の項目をカバーしています: + + * モデル API とデータベース API (``tests/modeltests/``). + * キャッシュシステム (``tests/regressiontests/cache.py``). + * ``django.utils.dateformat`` モジュール + (``tests/regressiontests/dateformat/``). + * データベースの型キャスト (``tests/regressiontests/db_typecasts/``). + * テンプレートシステム (``tests/regressiontests/templates/`` および + ``tests/regressiontests/defaultfilters/``). + * ``QueryDict`` オブジェクト (``tests/regressiontests/httpwrappers/``). + * markup テンプレートタグ (``tests/regressiontests/markup/``). + * ``django.utils.timesince`` モジュール + (``tests/regressiontests/timesince.py``). + +テストスイートに対する協力は何でも歓迎します! + +Django のテストは全て, Django に付属のアプリケーションテストインフラを使っ +ています.テストの書き方の詳細は `Django アプリケーションのテスト`_ を参照 +してください. + +.. _`Django アプリケーションのテスト`: ../testing/ + +.. _Running the unit tests: + +単体テストの実行 +---------------------- + +テストを実行するには, ``tests/`` ディレクトリ下に移って以下のように入力し +ます:: + + ./runtests.py --settings=path.to.django.settings + +そうです.テストには設定モジュールが必要なだけでなく,データベース設定の情 +報,つまり ``DATABASE_ENGINE``, ``DATABASE_USER`` および +``DATABASE_PASSWORD`` も必要です.また,全てのテストをパスするには, +``ROOT_URLCONF`` 設定 +(この値は単にあればよいだけで,内容は無視されます)と, ``SITE_ID`` 設定 +(整数ならどんな値でもかまいません) も指定しておかねばなりません. + +単体テストは既に作成済みのデータベースに影響を及ぼすことはありません.単体 +テストは ``django_test_db`` というデータベースを作成しますが,これはテスト +終了時に削除されます.また,この理由から,テストを行うユーザアカウントには +``CREATE DATABASE`` を実行する権限が必要です. + +.. _Requesting features: + +機能に関する要望 +=================== + +私達は常に Django を改良しようと努めています.その中で,皆さんから寄せられ +る要望は一つの鍵になっています.効果的に要望を出すコツをいくつか紹介してお +きます: + + * チケットトラッカではなく, `django-developers`_ に要望を出して下さい. + メーリングリストの方が多くの人の目に触れやすいからです. + + * 不足している機能と,それをどのように実装すればよいと思っているかを, + すっきりと,かつ詳細に説明してください.可能ならサンプルコード (実際 + に動かなくても構いません) をつけてください. + + * *なぜ* その機能を取り入れたいのかを説明してください.自明な場合もあり + ますが, Django は実際の開発者が実際の仕事に使うために設計されている + ので,ある機能がどのようにユーザの役に立つのかを説明する必要がありま + す. + +ほとんどのオープンソースプロジェクトと同じく,コードは大きな説明力を持って +います.追加したい機能のコードを書く意志があるか,(さらに望ましいのは) すで +に書き上げているのなら,ずっと受け入れられやすくなるでしょう.大がかりな機 +能で,複数の開発者が必要になりそうなら,いつでも喜んで実験用ブランチをリポ +ジトリに作成します.詳しくは次節を参照してください. + +.. _Branch policy: + +ブランチの管理ポリシ +==================== + +一般に,ほとんどの開発は trunk で行われており, trunk は安定に保たれていま +す. trunk のコードは,いついかなるときでも実運用サイトを動作させられなけれ +ばなりません. + +このため,大規模なアーキテクチャ上の変更,一つのパッチに収まらないくらい大 +きな変更を伴う場合や,多くの人が関わる必要のある変更の場合には,専用のブラ +ンチを作成します.例えば `i18n ブランチ`_ を見てください.この手の変更を行 +いたいと考えていて,作業をしたい場合には, `django-developers`_ でブランチ +を作成してもらうよう問い合わせて下さい.変更を試すのに必要な文だけのブラン +チを作成します. + +ツリーの一部にしか作業しない場合でも,常に Django ツリー全体のブランチを作 +成します.これはブランチへのスイッチ作業を苦痛なく行えるようにするためです. + +ブランチで作業している開発者は, trunk の変更を定期的にブランチにマージせね +ばなりません.少なくとも週に一度はマージしてください. trunk からマージを行 +う度に,マージとリビジョン番号を commit メッセージに記載してください. + +ブランチが安定していて, trunk へのマージ準備が完了したら, +`django-developers`_ にアラートを投稿します. + +あるブランチがマージされると,そのブランチは「死んだ」ものとみなされます. +死んだブランチには書き込めなくなり,古いブランチは定期的に「刈り取られ」 +ます. SVN への世話焼きを最小限にするため,ブランチから trunk へのマージは +一度しか行いません. + +.. _Using branches: + +ブランチを使う +-------------- + +ブランチをテストするには,二つの作業が必要です: + + * 該当するブランチのコードを Subversion から取得します. + + * Python の site-package ディレクトリが,該当ブランチの ``django`` + を含むように設定します. + + +.. _Getting the code from Subversion: + +Subversion からコードを取り出す +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +ブランチコードの最新版を入手するには Subversion を使います:: + + svn co http://code.djangoproject.com/svn/django/branches// + +```` はブランチの名前です.ブランチの名前については +`ブランチ名一覧 `_ +を参照してください. + +既存の Django を Subversion からソースコードをチェックアウトして使っている +場合には,ディレクトリ全体を特定のバージョンに自動的に変換できます. +``django`` ディレクトリの下で以下のコマンドを実行してください:: + + svn switch http://code.djangoproject.com/svn/django/branches// + +``svn co`` ではなく ``svn switch`` を使う利点は, ``switch`` コマンドを使っ +た場合,ローカルコピー上で既に変更済みの内容についてはファイルを変更しない +点にあります. ``switch`` はローカルコピー上の変更を "スイッチ先の" コード +にマージします. ``svn switch`` には欠点もあります.それは,ローカルコピー +上でコードに変更を加えた場合,スイッチ先のコードにも同じ部分に変更があると +衝突するという問題です. + +(``svn switch`` を使う場合には,次の節で述べるような,Pythonのモジュール検 +索パスを変更する操作は必要ありません.) + +.. _list of branch names: http://code.djangoproject.com/browser/django/branches + +.. _Pointing Python at the new Django version: + +Python に別のバージョンの Django を使わせる +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +ブランチのコードを取り出したら,ブランチの ``site-packages`` ディレクトリ +の構成を変更して,ブランチ版の ``django`` ディレクトリを使えるようにする必 +要があります. +(``site-packages`` ディレクトリは ``/usr/lib/python2.4/site-packages`` や +``/usr/local/lib/python2.4/site-packages``, ``C:\Python\site-packages`` +などにあります.) + +もっとも簡単な方法は,元の ``django`` ディレクトリを ``django.OLD`` のよう +な別の名前に変えて, trunk などから取り出したバージョンのコードをコピーし, +名前を ``django`` に変更します. + +別の方法として, ``django`` と言う名前のシンボリックリンクを作成して,特定 +のブランチの ``django`` パッケージの場所を指すという方法もあります.元に戻 +したい場合には,シンボリックリンクが元のコードを指すように変更しなおすだけ +です. + +第三の方法は, +`パスファイル `_ +(``.pth``) を使うというものです.この方法は, (シンボリックリン +クを使えない Windows を含む) 全てのシステムで利用できます.まず, +``site-packages`` ディレクトリに, ``django`` という名前のファイルやディレ +クトリ,シンボリックリンクがない状態にしてください.次に, ``django.pth`` +という名前のテキストファイルを作成して, ``site-packages`` ディレクトリの直 +下に保存します.このファイルには,使いたい Django の置かれているパスを一行 +で記述します.コメントを追加しても構いません.複数のブランチを指定できるよ +うにしたパスファイルの例を以下似示します.特定のブランチ (例えば 'trunk') +を使いたい場合,その行のコメントを解除して,他の行を全てコメント化します:: + + # トランク (trunk): svn リポジトリの + # http://code.djangoproject.com/svn/django/trunk/ + # からチェックアウトしたもの + # + /path/to/trunk + + # ブランチ (branch): ブランチ名 を svn リポジトリの + # http://code.djangoproject.com/svn/django/branches// + # からチェックアウトしたもの + # + #/path/to/ + + # Windows の場合は以下のような形式にします: + # C:/path/to/ + +Django 0.95 やそれ以前のバージョンをインストールしていて,インストールに +``python setup.py install`` を使った場合, ``django`` ではなく +``Django-0.95-py2.4.egg`` といった名前のディレクトリになっているでしょう. +この場合, ``setuptools.pth`` を編集して,該当する Django の ``.egg`` +の書かれた行を削除してから, ``django`` のブランチを ``site-packages`` にコ +ピーします. + +.. _path file: http://docs.python.org/lib/module-site.html + +.. _Official releases: + +公式リリース +============ + +Django のリリース番号は以下のようにして付けられます: + + * バージョンは ``A.B`` または ``A.B.C`` という形式でつけられます. + + * ``A`` はメジャーバージョン番号で,増えるのは Django に重大な変更が加 + えられ,変更が必ずしも以前のバージョンと互換でない場合だけです.従っ + て, Django 6.0 で動いたコードは Django 7.0 では動かなくなるかもしれ + ません. + + * ``B`` はマイナーバージョン番号で,比較的大きいながらも後方互換性を保っ + た変更の際に増えます. Django 6.4 向けに書かれたコードは Django 6.5 + でも動作するでしょう. + + マイナーリリースでは,以前のリリースの特定の機能を撤廃することがあり + ます.バージョン ``A.B`` の機能が撤廃された場合,撤廃された機能は + ``A.B+1`` では動作します. ``A.B+2`` では + ``PendingDeprecationWarning`` 警告を送出しますが動作します. + ``A.B+3`` では完全に機能を削除します.メジャーポイントリリースでは撤 + 廃済みの仕様を全て削除します. + + * ``C`` はマイクロバージョンで,バグやセキュリティ修正の度に増えます. + マイクロバージョンは以前のマイクロバージョンと 100% 後方互換性を保ち + ます. + + * 場合によってはリリース候補 (release candidate) を作成します.リリース + 候補のバージョン番号は ``A.BrcN`` の形式で, ``A.B`` の ``N`` 番目の + リリース候補であることを表します. + +以上のバージョン番号スキームの例外として,1.0 以前の Django のコード +があります. 1.0 リリース以前のコードでは,後方互換性を全く保証していません. + +Subversion 上では, Django の各リリースは `tags/releases_` でタグづけされて +います.trunk 由来ではないバグフィクスリリースやセキュリティ修正リリースを +出す必要画ある場合,該当リリースは ``branches/releases`` にコピーされ, +バグフィクスリリースになります. + +.. _Deciding on features: + +仕様に関する決定 +================ + +ある仕様の要望が出て議論が始まると,そのうち仕様を取り入れるべきか棄却すべ +きかという決定をせねばなりません. + +私達は,可能な場合はいつでもまずおおまかな合意を形成しようと試みます.その +後,たいていは `django-developers`_ において,その機能について正式でない投 +票を行います.投票では, Apache や Python で使われている形式を採用しており, +投票は +1, +0, -0, or -1 のいずれかを用いて行います.これらの票の大雑把な解 +釈は以下の通りです: + + * +1: "これはいい.強く同意します (I love the idea and I'm strongly + committed to it.)" + + * +0: "いいんじゃないかな (Sounds OK to me.)" + + * -0: "あまりわくわくしないが,反対もしない (I'm not thrilled, but I + won't stand in the way.)" + + * -1: "強く反対.このアイデアが実現したらとても嫌 (I strongly disagree + and would be very unhappy to see the idea turn into reality.)" + +django-developers での投票は正式なものではありませんが,その結果は真摯に受 +け止められます.適切な投票期間を経て,明らかな合意を形成できた場合には,投 +票の決定に従うでしょう. + +とはいえ,つねに合意を形成できるわけではありません.その場合,完全コミッタ +全員の中で十分に議論を重ねた後,最終判断を慈悲深き終身独裁者 (Benevolent +Dictators for Life) である Adrian と Jacob に委ねることとします. + +.. _Commit access: + +commit 権限 +============= + +Django プロジェクトには二種類のコミッタがいます: + +完全コミッタ (full committers) + 長期間にわたって Django のコードベースに貢献してきており,メーリングリ + ストにおいても礼儀正しく親切で, Django の開発に十分な時間を割けること + が分かっている人達です. + + 完全な commit 権限者の敷居は極めて高いものです.全ての完全コミッタによ + る全会一致でのみ受け入れることとし,その決定は覆りません. + +部分コミッタ (partial committers) + 「個別領域のエキスパート」です.管轄下にあるサブシステムのコードに直接 + チェックインする権限を持ち,サブシステムの懸案事項に対する正式な投票権 + を持ちます.このタイプの権限は, Django の大きなサブフレームワーク + に貢献し,継続してメンテナンスを続けたい人に与えられるものです. + + 完全コミッタと同様,部分コミッタの受け入れも全ての完全コミッタ (と同じ + 領域の部分コミッタ) による全会一致でのみ受け入れることとします.とはい + え,敷居はやや低く,個別領域で十分な専門性を示しているということで十分 + です. + +コミット権限を得たければ,現在コミッタを勤めているだれかに個人的にコンタク +トしてください.コミット権限を公の場でリクエストするのはフレームの元であり, +一切無視します. + +.. _`コミュニティのページ`: http://www.djangoproject.com/community/ +.. _`チケットトラッカ`: http://code.djangoproject.com/newticket +.. _`トラッカを検索`: http://code.djangoproject.com/search +.. _`パッチつきのチケットのリスト`: http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&has_patch=1&order=priority +.. _`i18n ドキュメント`: ../i18n/ +.. _`i18n ブランチ`: http://code.djangoproject.com/browser/django/branches/i18n + +.. _community page: http://www.djangoproject.com/community/ +.. _ticket tracker: http://code.djangoproject.com/newticket +.. _django-developers: http://groups.google.com/group/django-developers +.. _FAQ: ../faq/ +.. _search the tracker: http://code.djangoproject.com/search +.. _django-users: http://groups.google.com/group/django-users +.. _`#django`: irc://irc.freenode.net/django +.. _list of tickets with patches: http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&has_patch=1&order=priority +.. _PEP 8: http://www.python.org/peps/pep-0008.html +.. _i18n documentation: ../i18n/ +.. _i18n branch: http://code.djangoproject.com/browser/django/branches/i18n +.. _`tags/releases`: http://code.djangoproject.com/browser/django/tags/releases diff --git a/csrf.txt b/csrf.txt new file mode 100644 index 0000000..b0b4ba2 --- /dev/null +++ b/csrf.txt @@ -0,0 +1,82 @@ +============================================== +クロスサイトリクエストフォージェリ (CSRF) 対策 +============================================== + +:revision-up-to: 4805 (release 0.96) + +CsrfMiddleware クラスは,簡単に使える `クロスサイトリクエストフォージェリ`_ +対策を提供しています.このタイプの攻撃は,悪意あるウェブサイトが,あなたの +ウェブサイトに対して,ログイン済みユーザの権限で何らかの操作を行うように作 +られたリンクやフォームボタンを自分のサイトに設置しておき,ログイン済みのユー +ザがユーザが自分のブラウザを使ってボタンやリンクをクリックするように仕向け +ることで起こります. + +CSRF 攻撃に対する第一の防御は, GET リクエストから副作用を取り除くというも +のです. POST リクエストに対する防御は,このミドルウェアをインストール済み +ミドルウェアリストに追加して実現できます. + +.. _`クロスサイトリクエストフォージェリ`: + http://www.squarefree.com/securitytips/web-developers.html#CSRF +.. _Cross Site Request Forgeries: + http://www.squarefree.com/securitytips/web-developers.html#CSRF + +.. _How to use it: + +使い方 +====== + +``'django.contrib.csrf.middleware.CsrfMiddleware'`` ミドルウェアを +``MIDDLEWARE_CLASSES`` に追加してください.このミドルウェアは +SessionMiddleware よりも後にレスポンスを処理せねばならないので,リスト中の +SessionMiddleware よりも前に配置します.また,圧縮のような操作が入る前のレ +スポンスを処理せねばならないので, GZipMiddleware よりも後に配置します. + +.. _How it works: + +仕組み +====== + +CsrfMiddleware は以下のような処理を行います: + +1. CsrfMiddleware は,サーバから出てゆくレスポンス内の 'POST' フォーム全て + に対して 'csrfmiddlewaretoken' という名前の隠しフィールドを追加します. + このフィールドの値はセッション ID とシークレット文字列の和をハッシュした + ものになります.セッション ID が設定されていない場合,レスポンスに対する + 変更は行いません.このため,セッションをともなわないリクエストに対しては + 非常にわずかなパフォーマンスペナルティしかもたらしません. + +2. セッションクッキーのセットされた全ての POST リクエストに対し, + 'csrfmiddlewaretoken' がセットされていて,かつ正しい値になっているか調べ + ます.正しい値でなければ, 403 エラーを返します. + +これらの処理により,あなたのウェブサイト由来のフォームだけが POST を送り返 +せるようになります. + +このミドルウェアは, HTTP POST リクエスト (と POST フォーム) だけを対象にし +ています. (HTTP GET と POST を正しく使い分けてさえいれば) GET リクエストは +副作用をもたらさないので, GET リクエストを使った CSRF 攻撃はなんら威力を持 +たなくなります. + +セッションクッキーを伴わない POST リクエストは保護されませんが,セッション +クッキーを伴わないようなフォームに対しては,攻撃側のウェブサイトはリクエス +トをどのようにでも作れてしまうので,そもそも保護する意味はありません. + +CsrfMiddleware はレスポンスを変更する前に Content-Type をチェックし, +'text/html' または 'application/xml+xhtml' のページだけを変更します. + +.. _Limitations: + +制限 +==== + +CsrfMiddleware を動作させるには, Django のセッションフレームワークが必要で +す.手動でクッキーを設定するカスタムの認証システムなどを使っている場合には +うまく動作しません. + +アプリケーションで HTML ページやフォームを普通とは違うやり方で生成している +場合 (JavaScript の document.write 文などで HTML フラグメントを送信するよう +な場合),フォームの隠しフィールドを追加するフィルタを回避してしまうかもしれ +ません.そのような場合,フォームの提出は常に失敗してしまいます.ただし, +CSRF 対策トークンを取得し,提出されるフォームに必ずトークンが入るようにすれ +ば,このミドルウェアを使う余地はあるでしょう. + diff --git a/databases.txt b/databases.txt new file mode 100644 index 0000000..331ee59 --- /dev/null +++ b/databases.txt @@ -0,0 +1,193 @@ +========================== +データベースのサポート状況 +========================== + +:revision-up-to: 4805 (release 0.96) + +Django は可能な限り全てのデータベースバックエンドをサポートしようとしていま +すが,残念ながら全てのサーバが全く同じ仕様というわけではないので,どの機能 +をサポートすべきか,どういった仕様を仮定するかといった設計上の判断を下して +います. + +このドキュメントでは,このドキュメントでは, Django を使う上で関係のあるデー +タベース機能について説明します.ただし,このドキュメントは特定のデータベー +スサーバ向けのドキュメントとして書かれたものではなく,リファレンスマニュア +ルでもありません. + +.. _MySQL Notes: + +MySQL に関する注意 +================== + +Django はデータベースがトランザクションや参照の一貫性 (referential +integrity), Unicode (UTF-8 エンコーディング) をサポートしていることを想定 +して書かれています.好運なことに, MySQL_ バージョン 3.23 以降でこれらの機 +能全てをサポートしています.従って, 3.23 や 4.0 をバックエンドとして使うの +は可能なのですが, 4.1 や 5.0 を使った方がトラブルに巻き込まれにくいでしょ +う. + +MySQL 4.1 +--------- + +`MySQL 4.1`_ では,文字セットのサポートを大幅に改良しています. 4.1 では, +データベース全体から,テーブル毎,カラム毎にいたるまで個別にデフォルトの文 +字セットを指定できます.以前のバージョンでは,サーバ全体に対する文字セット +の設定しかできませんでした.また, 4.1 になってはじめてオンザフライで文字セッ +トを変更できるようになりました. 4.1 にはビューのサポートもありますが, +Django はまだこの機能をサポートしていません. + +MySQL 5.0 +--------- + +`MySQL 5.0`_ では,全てのデータベーススキーマに関する詳細なデータの入った +``information_schema`` というデータベースが追加されました. +``information_schema`` が存在すると, Django はこのデータベースに対して +``inspectdb`` 機能を適用します. 5.0 ではまた,ストアドプロシジャのサポート +も追加されましたが, Django はまだこの機能をサポートしていません. + +.. _MySQL: http://www.mysql.com/ +.. _`MySQL 4.1`: http://dev.mysql.com/doc/refman/4.1/en/index.html +.. _`MySQL 5.0`: http://dev.mysql.com/doc/refman/5.0/en/index.html + +.. _Storage Engines: + +ストレージエンジン +------------------ + +MySQL は複数の +`ストレージエンジン`_ +(以前はテーブルタイプ: table type と呼ばれていたもの) を選択できます. +デフォルトのストレージエンジンはサーバ設定で変更できます. + +デフォルトのストレージエンジンは MyISAM_ です. MyISAM の短所は,現状ではト +ランザクションや外部キーをサポートしていないという点です.一方, MyISAM は, +現状で,全文インデクスの生成や全文検索をサポートしている唯一のストレージエ +ンジンです. + +InnoDB_ エンジンは完全なトランザクション機能と外部キー参照をサポートしてい +ます. + +BDB_ エンジンは InnoDB と同様,完全なトランザクション機能を外部キー参照をサ +ポートしていますが,やや時代送れになりつつあるようです. + +SolidDB_ や Falcon_ といった `その他のストレージエンジン `_ +まだまだ圏外の話です.現状では,おそらく InnoDB が最良の選択でしょう. + +.. _storage_engines: http://dev.mysql.com/doc/refman/5.0/en/storage-engines.html +.. _ストレージエンジン: storage_engines_ +.. _MyISAM: http://dev.mysql.com/doc/refman/5.0/en/myisam-storage-engine.html +.. _BDB: http://dev.mysql.com/doc/refman/5.0/en/bdb-storage-engine.html +.. _InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb.html +.. _Other storage engines: http://dev.mysql.com/doc/refman/5.1/en/storage-engines-other.html +.. _SolidDB: http://forge.mysql.com/projects/view.php?id=139 +.. _Falcon: http://dev.mysql.com/doc/falcon/en/index.html + +MySQLdb +------- + +`MySQLdb`_ は Python から MySQL にアクセスするためのインタフェースです. +MySQLdb はバージョン 1.2.1 から MySQL-4.1 以降をサポートするようになりまし +た.4.1 以前のバージョンを使っているなら, *たぶん* 1.2.0 でも動作するでしょ +う. + +.. _MySQLdb: http://sourceforge.net/projects/mysql-python + +.. _Creating your database: + +データベースを作成する +---------------------- + +コマンドラインツールを使って,以下の SQL を発行すれば +`データベースを作成 `_ +できます:: + + CREATE DATABASE CHARACTER SET utf8; + +これで,全てのテーブルとカラムがデフォルトで UTF-8 を使うようになります. + +.. _create your database: http://dev.mysql.com/doc/refman/5.0/en/create-database.html + +.. _Connecting to the database: + +データベースに接続する +---------------------- + +`設定に関するドキュメント `_ も参照してください. + +接続に関する設定は,以下の順に適用されます: + + 1. ``DATABASE_OPTIONS`` + 2. ``DATABASE_NAME``, ``DATABASE_USER``, ``DATABASE_PASSWORD``, ``DATABASE_HOST``, + ``DATABASE_PORT`` + 3. MySQL のオプション設定ファイル + +別の言い方をするなら, ``DATABASE_OPTIONS`` 内にデータベースの名前を設定す +ると,その内容は ``DATABASE_NAME`` よりも優先順位が高くなり,さらに +``DATABASE_NAME`` は +`MySQL のオプション設定ファイル `_ +の内容をオーバライドするということです. + +MySQL のオプション設定ファイルを使う例を以下に示します:: + + # settings.py + DATABASE_ENGINE = "mysql" + DATABASE_OPTIONS = { + 'read_default_file': '/path/to/my.cnf', + } + + # my.cnf + [client] + database = DATABASE_NAME + user = DATABASE_USER + passwd = DATABASE_PASSWORD + default-character-set = utf8 + +この他にも,MySQLdb の接続オプションには, ``ssl``, ``use_unicode``, +``init_command``, ``sql_mode`` といった便利なものがあります.詳しくは +`MySQLdb のドキュメント `_ を参照して +ください. + +.. _settings documentation: http://www.djangoproject.com/documentation/settings/#database-engine +.. _MySQL option file: http://dev.mysql.com/doc/refman/5.0/en/option-files.html +.. _MySQLdb documentation: http://mysql-python.sourceforge.net/ + +.. _Creating your tables: + +テーブルを作成する +------------------ + +Django はスキーマを作成する際にストレージエンジンを指定しません.そのため, +テーブルは常にサーバに設定されたデフォルトのストレージエンジンで作成されま +す.作成されるテーブルを特定のタイプにしたければ,データベースサーバのデフォ +ルトストレージエンジンを Django で使いたいストレージエンジンに合わせるのが +一番簡単です. + +ホスティングサービスを使っていて,サーバのデフォルトのストレージエンジンを +変更できない場合,二つの選択肢があります. + + * テーブルが作成された後に,以下のようなクエリを発行して,ストレージ + エンジンを (InnoDB) などに変更します:: + + ALTER TABLE ENGINE=INNODB; + + テーブルが沢山ある場合には,これは相当骨がおれることでしょう. + + * あるいは,テーブルを作成する前に, MySQLdb の ``init_command`` オプショ + ンを使います:: + + DATABASE_OPTIONS = { + ... + "init_command": "SET storage_engine=INNODB", + ... + } + + このように設定しておくと,接続時にデフォルトのストレージエンジンが変更 + されます.ただし,テーブルが全て作成され,運用環境で動き始めたら,この + オプションを外しておかねばなりません. + + * もう一つ, syncdb 時にストレージエンジンを変更する方法が, Wiki の + `AlterModelOnSyncDB `_ + にあります. + +.. _AlterModelOnSyncDB: http://code.djangoproject.com/wiki/AlterModelOnSyncDB + diff --git a/db-api.txt b/db-api.txt new file mode 100644 index 0000000..9c919c7 --- /dev/null +++ b/db-api.txt @@ -0,0 +1,1936 @@ +============================= +データベース API リファレンス +============================= + +:revision-up-to: 4805 (release 0.96) + +`データモデル`_ を作成したら,次はデータベースからデータを取り出す必要があ +ります.このドキュメントでは,モデルから利用できるデータベース抽象化 API と, +オブジェクトを生成,取得,更新する方法について説明します. + +.. _`データモデル`: ../model_api/ +.. _`data models`: ../model_api/ + +このリファレンスでは,以下のような Poll アプリケーションを参考に話を進めま +す:: + + class Blog(models.Model): + name = models.CharField(maxlength=100) + tagline = models.TextField() + + def __str__(self): + return self.name + + class Author(models.Model): + name = models.CharField(maxlength=50) + email = models.URLField() + + def __str__(self): + return self.name + + class Entry(models.Model): + blog = models.ForeignKey(Blog) + headline = models.CharField(maxlength=255) + body_text = models.TextField() + pub_date = models.DateTimeField() + authors = models.ManyToManyField(Author) + + def __str__(self): + return self.headline + + +.. _Creating objects: + +オブジェクトの生成 +================== + +Django では,データベーステーブル上のデータを Python オブジェクトで表現する +ために,モデルクラスがデータベーステーブルを表現し,クラスのインスタンスが +テーブル上のレコードを表現するという直感的なシステムを使っています. + +オブジェクトを生成するには,キーワード引数を使ってモデルクラスのインスタン +スを生成し, ``save()`` メソッドを呼び出してデータベースに保存します. + +モデルクラスは Python パス上のどこからでも import でき,期待通りに動作しま +す (わざわざこのような説明をするのは,以前のバージョンの Django ではモデル +の import 方法がかなり風変わりだったからです). + +モデルが ``mysite/blog/models.py`` というファイルで定義されているとすると, +オブジェクトの作成は以下の例のようになります:: + + from mysite.blog.models import Blog + b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') + b.save() + +この操作によって,背後では ``INSERT`` SQL 文が実行されます. Django はユー +ザが明示的に ``save()`` を呼び出すまでデータベースを操作しません. + +ワンステップでオブジェクトを生成して保存するには `create`__ メソッドを使 +います。 + +__ `create(**kwargs)`_ + +.. _Auto-incrementing primary keys: + +主キーの自動インクリメント +-------------------------- + +モデルに ``AutoField`` ,すなわち自動インクリメントされる主キーがある場合に +は,オブジェクトに対して最初に ``save()`` を呼び出したときに自動インクリメ +ント値が計算され,保存されます. + +例えば:: + + b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.') + b2.id # b には ID がないので None を返します. + b2.save() + b2.id # 新たに保存されたオブジェクトの ID を返します. + +ID の値は Django ではなくデータベースによって計算されるので, ``save()`` を +呼び出すまでは ID の値は分かりません. + +(利便性のため,明示的に ``primary_key=True`` を指定したフィールドを作成しな +いかぎり,デフォルトでは各モデルに ``id`` という名前の ``AutoField`` +が追加されます.詳しくは `AutoField のドキュメント`_ を参照してください.) + +.. _`AutoField のドキュメント`: ../model_api/#autofield +.. _AutoField documentation: ../model_api/#autofield + +.. _Explicitly specifying auto-primary-key values: + +自動主キーの値を明示的に指定する +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +モデルが ``AutoField`` を持っていて,新たなオブジェクトの ID を保存時に明示 +的に指定したい場合, ID を自動的に決定させずに保存前に明示的に指定してくだ +さい. + +例えば:: + + b3 = Blog(id=3, name='Cheddar Talk', tagline='Thoughts on cheese.') + b3.id # Returns 3. + b3.save() + b3.id # Returns 3. + +自動主キーの値を手動で割り当てる場合,決して既に存在する主キーの値を割り当 +てないようにしてください! 明示的な主キー値を持った新たなオブジェクトを作成 +し,その主キーがすでにデータベース上に存在する場合, Django は保存操作を新 +たなオブジェクトの作成ではなく,既存のオブジェクトの変更とみなします. + +上の ``'Cheddar Talk'`` ブログを例にとると,以下の例はデータベース上の既存 +のレコードをオーバライドしてしまいます:: + + b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.') + b4.save() # Overrides the previous blog with ID=3! + +この理由については後述の `UPDATE と INSERT の区別`_ を参照してください. + +主キーの衝突がないとはっきり判っている場合なら,自動主キーの値の明示的な指 +定は大量のオブジェクトを保存する際にきわめて便利です. + +.. _Saving changes to objects: + +オブジェクトへの変更を保存する +============================== + +すでにデータベース上にあるオブジェクトへの変更を保存するには ``save()`` を +使います. + +``Blog`` インスタンス ``b5`` がすでにデータベース上にあるとすると,以下の例 +は ``b5`` の名前を変更して,データベース上のレコードを更新します:: + + b5.name = 'New name' + b5.save() + +この例では,背後で ``UPDATE`` SQL 文が実行されています. Django は明示的に +``save()`` を呼び出すまでデータベースを操作しません. + +``save()`` メソッドには戻り値がありません. + +.. _How Django knows to UPDATE vs. INSERT: + +UPDATE と INSERT の区別 +----------------------- + +Django データベースオブジェクトがオブジェクトの作成と変更に同じ ``save()`` +メソッドを使っていることにお気づきかもしれませんね. Django は ``INSERT`` +と ``UPDATE`` SQL 文のどちらを使うべきかの判断を抽象化しています.具体的 +に言うと, ``save()`` を呼び出したときに,Django は以下のアルゴリズムに従い +ます: + + * オブジェクトの主キー属性の評価値が ``False`` でない場合 (``None`` や + 空文字列の場合などでない場合) , Django は ``SELECT`` クエリを使って, + 該当する主キーを持つレコードが存在するかどうか調べます. + * 該当する主キーを持つレコードがデータベース上に存在する場合には + ``UPDATE`` クエリを使います. + * オブジェクトの主キー属性が設定 *されていない* 場合や,主キーが設定さ + れているが該当するレコードは存在しない場合, ``INSERT`` を使います. + +新たなオブジェクトを保存する際,まだ使われていない値を主キーに指定できる保 +証がないかぎり,主キーの値を明示的に指定しないよう注意してください.詳しく +は上記の `自動主キーの値を明示的に指定する`_ を参照してください. + +.. _Retrieving objects: + +オブジェクトの取得 +================== + +オブジェクトをデータベースから取得するには,モデルクラスのマネジャ +(``Manager``) を介してクエリセット (``QuerySet``) を構築します. + +クエリセットはデータベース上にあるオブジェクトの集まりを表現しています. +クエリセットには,集合を指定パラメタに従って絞り込むための条件である +*フィルタ (filter)* がゼロ個から複数個あります. SQL 用語でいえば, +クエリセットは ``SELECT`` 文であり,フィルタは ``WHERE`` や ``LIMIT`` +のような限定節にあたります. + +クエリセットはモデルのマネジャから取得します.モデルには最低一つの +マネジャがあり,デフォルトでは ``objects`` という名前がついています. +マネジャにはモデルクラスから直接アクセスしてください:: + + Blog.objects # + b = Blog(name='Foo', tagline='Bar') + b.objects # AttributeError: "Manager isn't accessible via Blog instances." + +(「テーブルレベル」の操作と「レコードレベル」の操作を分離させるため,マネジャ +はモデルのインスタンスではなくモデルクラスだけからアクセスできるようになっ +ています.) + +モデル内でのクエリセットの主なソースはマネジャです.マネジャは,データベー +スオブジェクト上の全てのオブジェクトを表す「ルートの」クエリセットであるか +のように振舞います.例えば,初期クエリセットである ``Blog.objects`` には, +データベース上の全ての ``Blog`` オブジェクトが入っています. + + +.. _Retrieving all objects: + +全てのオブジェクトの取得 +------------------------ + +テーブルからオブジェクトを取得する最も単純な方法では,全てのオブジェクトを +取得します.マネジャの ``all()`` メソッドを使って下さい. + +例えば:: + + all_entries = Entry.objects.all() + +``all()`` メソッドはデータベース上の全てのオブジェクトを表現するクエリセッ +トを返します. + +(``Entry.objects`` がクエリセットを返すというのなら,なぜ単に +``Entry.objects`` と書かないのでしょうか?それは,ルートのクエリセットであ +る ``Entry.objects`` が特別扱いされていて,値評価できないようになっているか +らです. ``all()`` メソッドは,値評価 *できる* クエリセットを返します. + + +.. _Filtering objects: + +オブジェクトのフィルタ操作 +-------------------------- + +マネジャによって提供されるクエリセットを使えば,データベーステーブル上の全 +てのオブジェクトを表せます.とはいえ,通常は全オブジェクトの集合からサブセッ +トだけを取り出したいことでしょう. + +サブセットを作成するには,フィルタ条件を追加して,初期クエリセットをリファ +インする必要があります.クエリセットの洗練には,主に二つの方法があります: + +``filter(**kwargs)`` + 指定した照合パラメタに一致するオブジェクトの集合を表現する,新たなクエ + リセットを返します. + +``exclude(**kwargs)`` + 指定した照合パラメタに一致 *しない* オブジェクトの集合を表現する,新た + なクエリセットを返します. + +照合パラメタ (上の関数定義における ``**kwargs``) は,後述の +`フィールドの照合`_ で解説するフォーマットにせねばなりません. + +例えば, 2006 年のブログエントリを表すクエリセットを取得するには,以下のよ +うに ``filter()`` を使います:: + + Entry.objects.filter(pub_date__year=2006) + +(``Entry.objects.all().filter(...)`` のように, ``all()`` を使わなくてもよ +いことに注意して下さい. ``all()`` を使っても問題なく動作しますが, +``all()`` が必要となるのはルートクエリセットから全てのオブジェクトを取り出 +したい場合だけです.) + + +.. _Chaining filters: + +フィルタの連鎖 +~~~~~~~~~~~~~~ + +クエリセットをリファインした結果は,それ自体クエリセットになります.従って, +リファイン操作は連鎖させられます.例えば:: + + Entry.objects.filter( + headline__startswith='What').exclude( + pub_date__gte=datetime.now()).filter( + pub_date__gte=datetime(2005, 1, 1)) + +上の例は,データベースの全てのエントリを表す初期クエリセットに対し, +``filter()`` をかけた後に ``exclude()`` を実行し,さらにもう一つ +``filter()`` をかけています.最終的に得られるのは, "What" で始まる +ヘッドラインのうち, January 1, 2005 から今日までの間に公開されたエントリに +なります. + +.. _Filtered QuerySets are unique: + +フィルタしたクエリセットは一意になる +------------------------------------ + +クエリセットのリファインを行うと,その都度新たなクエリセットを得ます.新た +なクエリセットは以前のクエリセットになんら縛られていません.リファイン操作 +のたびに,別個の独立したクエリセットが作成され,個別に保存したり,再利用し +たりできます. + +例えば:: + + q1 = Entry.objects.filter(headline__startswith="What") + q2 = q1.exclude(pub_date__gte=datetime.now()) + q3 = q1.filter(pub_date__gte=datetime.now()) + +これら 3 つのクエリセットは別個のものです.最初はヘッドラインが "What" で始 +まる全てのエントリの入ったベースのクエリセットです.二つ目のクエリセットは, +最初のクエリセットのサブセットであり, ``pub_date`` の値が現在時刻よりも大 +きいものを排除します.三つ目のクエリセットも最初のクエリセットのサブセット +で, ``pub_date`` の値が現在時刻よりも大きいものだけを選択するようになって +います.こうしたリファイン操作は,初期クエリセット (``q1``) に影響を及ぼし +ません. + +.. _QuerySets are lazy: + +クエリセットは遅延評価される +---------------------------- + +クエリセットの評価は遅延型 (lazy) です.すなわち,クエリセットの作成自体は +データベース操作を引き起こしません.クエリセットは *評価される* までデータ +ベースへのクエリを実行しないので,延々フィルタを重ねられます. + +.. _When QuerySets are evaluated: + +クエリセットはいつ評価されるのか +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +以下の方法を使うと,クエリセットを評価できます: + + * **イテレーション.** クエリセットはイテレーション可能オブジェクトであ + り,オブジェクトに対して最初にイテレーション操作を行ったときにデータ + ベースクエリを実行します.例えば,以下の例はデータベース中の全てのエ + ントリのヘッドラインを出力します:: + + for e in Entry.objects.all(): + print e.headline + + * **スライス.** `クエリセットに制約を課す`_ の節で説明しているように, + Python の配列スライス表記を使うとクエリセットをスライスできます.通常, + クエリセットに対するスライスは (未評価の) 別のクエリセットを返します + が,スライス表記に「ステップ (step)」パラメタを使った場合には,データ + ベースクエリを実行します. + + * **repr().** クエリセットに対して ``repr()`` を呼び出すと,クエリセッ + トは値評価されます.これは Python 対話インタプリタでの利便性のための + 仕様で, API を対話的に使うときに結果を即座に見られるようにしています. + + * **len().** クエリセットに対して ``len()`` を呼び出すと,クエリセッ + トは値評価されます.予想に違わず, ``len()`` はクエリ結果リストの長さ + を返します. + + 注意: クエリセット中のレコードの数を知りたいだけなら, ``len()`` は + *使わないでください* .レコード数の計算はデータベース上で SQL 文の + ``SELECT COUNT(*)`` 使って行う方が遥かに効率的であり,まさにその理由 + から Django では ``count()`` メソッドを提供しています.後述の + ``count()`` を参照してください. + + * **list().** クエリセットに対して ``list()`` を呼び出すと,値評価を強 + 制できます.例えば:: + + entry_list = list(Entry.objects.all()) + + とはいえ,この方法を使うと,Django が全ての要素のリストをメモリ上にロー + ドするため,巨大なメモリオーバヘッドを引き起こす可能性があるので十分 + 注意してください.これに対し,クエリセットに対するイテレーション操作 + では,必要な分だけデータをロードしてオブジェクトをインスタンス化する + という利点があります. + + +.. _Limiting QuerySets: + +クエリセットに制約を課す +------------------------ + +クエリセットの返す結果を特定の個数に制限したい場合には,配列スライス表記を +使います.これは SQL の ``LIMIT`` 節や ``OFFSET`` 節と等価になります. + +以下の例は,最初の 5 オブジェクトだけを返します (``LIMIT 5`` に相当します):: + + Entry.objects.all()[:5] + +以下の例は, 5 番目から 10 番目までのオブジェクトを返します +(``OFFSET 5 LIMIT 5`` に相当します):: + + Entry.objects.all()[5:10] + +一般に,クエリセットのスライスはクエリセットを返し,クエリの評価は行いませ +ん.例外はスライス表記に「ステップ (step)」パラメタを使ったときです.以下の +例では,クエリを実際に実行し,最初の 10 オブジェクト中から 1 つおきにオブジェ +クトを取り出したリストを返します:: + + Entry.objects.all()[:10:2] + +リストではなく *単一の* オブジェクトを取得したい場合 +(``SELECT foo FROM bar LIMIT 1`` のような場合) には,スライスではなく単純な +インデクス指定を行います.以下の例はデータベースのエントリをヘッドラインに +ついてアルファベット順に整列した後,最初の ``Entry`` を取得して返します:: + + Entry.objects.order_by('headline')[0] + +これはだいたい以下と同じになります:: + + Entry.objects.order_by('headline')[0:1].get() + +ただし,指定条件にマッチするオブジェクトがない場合,前者は ``IndexError``, +後者は ``DoesNotExist`` を送出します. + +.. _QuerySet methods that return new QuerySets: + +新たなクエリセットを返すクエリセットメソッド +-------------------------------------------- + +Django では,クエリセットの返す結果の形式や, SQL クエリの実行方法を変更す +るためのリファインメソッドを幅広く提供しています. + +``filter(**kwargs)`` +~~~~~~~~~~~~~~~~~~~~ + +指定の照合パラメタに一致するオブジェクトの入った新たなクエリセットを返しま +す. + +照合パラメタ (``**kwargs``) は後述の `フィールドの照合`_ で説明するフォーマッ +トにします.複数のパラメタを指定すると,背後の SQL 文では ``AND`` で結合さ +れます. + +``exclude(**kwargs)`` +~~~~~~~~~~~~~~~~~~~~~ + +指定の照合パラメタに一致 *しない* オブジェクトの入った新たなクエリセットを +返します. + +照合パラメタ (``**kwargs``) は後述の `フィールドの照合`_ で説明するフォーマッ +トにします.複数のパラメタを指定すると,背後の SQL 文では ``AND`` で結合さ +れ,制約条件節全体を ``NOT()`` で囲みます. + +以下の例では, ``pub_date`` が現在より未来の日時になっていて, *かつ* +``headline`` が "Hello" で始まる全てのエントリを除外します:: + + Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello') + +SQL 用語でいうと,以下のようなクエリの評価になります:: + + SELECT ... + WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello') + +また,以下の例では, ``pub_date`` が現在より未来の日時になっているか, +*または* ``headline`` が "Hello" で始まる全てのエントリを除外します:: + + Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello') + +SQL 用語でいうと,以下のようなクエリの評価になります:: + + SELECT ... + WHERE NOT pub_date > '2005-1-3' + AND NOT headline = 'Hello' + +二つ目の例の方が厳しい制約になっていることに注意して下さい. + +``order_by(*fields)`` +~~~~~~~~~~~~~~~~~~~~~ + +デフォルトでは, ``QuerySet`` の返す結果はモデルの ``Meta`` の ``ordering`` +オプションに指定した整列条件のタプルに従って整列されます. ``order_by`` を +使うと,この挙動を ``QuerySet`` 単位でオーバライドできます. + +例えば:: + + Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline') + +このクエリの結果は,まず ``pub_date`` で降順に並べ,次いで ``headline`` で +昇順に並べたものになります. ``"-pub_date"`` の先頭にあるマイナス記号が +*降順* 表しています.何も指定しないと昇順になります.整列をランダムに +したければ,以下のように "?" を使います:: + + Entry.objects.order_by('?') + +別のテーブルのフィールド値で整列させる場合,テーブル名をドット表記で指定し +ます:: + + Entry.objects.order_by('blogs_blog.name', 'headline') + +大小文字の区別を考慮して整列するかどうかを指定する方法はありません.大小文 +字の区別については, Django は現在使っているデータベースバックエンドの整列 +方法に従います. + +``distinct()`` +~~~~~~~~~~~~~~ + +SQL クエリに ``SELECT DISTINCT`` を使う新たな ``QuerySet`` を返します. +``distinct()`` を使うと,クエリ結果から重複する行をなくします. + +デフォルトでは, ``QuerySet`` は重複する行を除去しません.通常は, +``Blog.objects.all()`` のような単純なクエリは重複する行を含むような結果にな +らないため,これはあまり問題にはなりません. + +しかし,クエリが複数のテーブルにわたる場合, ``QuerySet`` の評価結果に重複 +する結果が入る場合があります.その場合には ``distinct()`` を使って下さい. + +``values(*fields)`` +~~~~~~~~~~~~~~~~~~~ + +``ValueQuerySet`` を返します. ``ValueQuerySet`` は ``QuerySet`` のサブクラ +スで,評価結果としてモデルインスタンスオブジェクトの代りに辞書のリストを返 +す ``QuerySet`` です. + +リスト中の各辞書は個々のオブジェクトを表現しており,キーがモデルオブジェク +トの各属性名に,対応しています. + +以下の例では, ``values()`` の辞書と通常のモデルオブジェクトを比較していま +す:: + + # リストには Blog オブジェクトが入ります. + >>> Blog.objects.filter(name__startswith='Beatles') + [Beatles Blog] + + # リストには辞書が入ります. + >>> Blog.objects.filter(name__startswith='Beatles').values() + [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}] + +``values()`` オプションの可変長の引数 ``*fields`` を取れます.このオプションは +``SELECT`` の制限に使うフィールド名を列挙したものです. ``fields`` を指定し +た場合,辞書には指定した名前のフィールドのキーと値だけが入ります. +``*fields`` を指定しなければ,辞書にはテーブルの全てのフィールドのキーと値 +が入ります. + +例を示します:: + + >>> Blog.objects.values() + [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}], + >>> Blog.objects.values('id', 'name') + [{'id': 1, 'name': 'Beatles Blog'}] + +``ValuesQuerySet`` が便利なのは,わずかな数のフィールドの値しか必要でなく, +モデルインスタンスオブジェクトの機能が必要でないと分かっている場合です. +必要なフィールドだけを選択すると,さらに効率的になります. + +最後に, ``ValuesQuerySet`` は ``QuerySet`` のサブクラスなので, +``QuerySet`` の全てのメソッドを持っている点に注意してください. +``ValuesQuerySet`` に対して ``filter()`` や ``order_by()`` といった操作を行 +えます.そう,以下の二つの呼び出しは等価になります:: + + Blog.objects.values().order_by('id') + Blog.objects.order_by('id').values() + +Django の作者たちは,全ての SQL 関係のメソッドを先に配置し,その後に (必要 +なら) 出力関係のメソッド (``values()`` など) を配置するやり方を好んでいます. +とはいえ,これは実際上問題ではないので,個人的な信条を反映させてかまいませ +ん. + +``dates(field, kind, order='ASC')`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``DateQuerySet`` を返します. ``DateQuerySet`` は ``QuerySet`` のサブクラス +で,評価結果としてクエリセット内のコンテンツの全日付を +``datetime.datetime`` オブジェクトとして返す ``QuerySet`` です. + +``field`` はモデルの ``DateField`` または ``DateTimeField`` の名前です. + +``kind`` は ``"year"``, ``"month"`` または ``"day"`` です. +結果リスト中の各 ``datetime.datetime`` オブジェクトは ``type`` の指定に従っ +て切り詰められます. + + * ``"year"`` フィールドの年部分の値の重複しないリストを返します. + * ``"month"`` フィールドの年/月部分の値の重複しないリストを返します. + * ``"day"`` フィールドの年/月/日部分の値の重複しないリストを返します. + +``order`` には結果の並び順を指定します.デフォルト値は ``'ASC'`` で, +``"ASC"`` または ``"DESC"`` にできます. + +例を示します:: + + >>> Entry.objects.dates('pub_date', 'year') + [datetime.datetime(2005, 1, 1)] + >>> Entry.objects.dates('pub_date', 'month') + [datetime.datetime(2005, 2, 1), datetime.datetime(2005, 3, 1)] + >>> Entry.objects.dates('pub_date', 'day') + [datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)] + >>> Entry.objects.dates('pub_date', 'day', order='DESC') + [datetime.datetime(2005, 3, 20), datetime.datetime(2005, 2, 20)] + >>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day') + [datetime.datetime(2005, 3, 20)] + + +``none()`` +~~~~~~~~~~ + +**開発版の Django で新たに追加された機能です** + +``EmptyQuerySet`` を返します. ``EmptyQuerySet`` とは,評価結果が常に空の +リストになるクエリセットです.関数の戻り値などで空の照合結果を返したいが, +呼び出し側が (空のリストなどではなく) クエリセットオブジェクトの戻り値を期 +待している場合に便利です. + +例:: + + >>> Entry.objects.none() + [] + + +``select_related()`` +~~~~~~~~~~~~~~~~~~~~ + +自動的に外部キーのリレーションを「追跡」し,クエリを実行したときにリレーショ +ン先のオブジェクトも加えて選択するような ``QuerySet`` を返します. +これはパフォーマンスを向上させるための機構で,クエリは (ときに非常に) 巨大 +になりますが,以後の外部キーへのリレーションでデータベースクエリが必要なく +なります. + +以下の例では,通常の照合と ``select_related()`` を使った照合との違いを比較 +しています.通常の照合は以下のようになります:: + + # データベースを操作します. + e = Entry.objects.get(id=5) + + # リレーション先の Blog オブジェクトを取得するために再度データベースを + # 操作します. + b = e.blog + +``select_related()`` を使った照合は以下のようになります:: + + # データベースを操作します. + e = Entry.objects.select_related().get(id=5) + + # e.blog は上のクエリで取得済みなので,データベースを操作しません. + b = e.blog + +``select_related`` は可能な限り外部キーを追跡することに注意してください.以 +下のようなモデル:: + + class City(models.Model): + # ... + + class Person(models.Model): + # ... + hometown = models.ForeignKey(City) + + class Book(models.Model): + # ... + author = models.ForeignKey(Person) + +の場合, ``Book.objects.select_related().get(id=4)`` +を実行すると,リレーションの張られた ``Person`` *に加えて* ``City`` もキャッ +シュします:: + + b = Book.objects.select_related().get(id=4) + p = b.author # Doesn't hit the database. + c = p.hometown # Doesn't hit the database. + + sv = Book.objects.get(id=4) # No select_related() in this example. + p = b.author # Hits the database. + c = p.hometown # Hits the database. + +``select_related()`` は ``null=True`` であるような外部キーカラムは追跡しな +いので注意してください. + +通常, ``select_related()`` を使うと,データベースの呼び出し回数を減らせる +ので,大幅にパフォーマンスを向上できます.しかし,リレーションが深くネスト +しているような状況では, ``select_related()`` が追跡するリレーションが「多 +すぎる」ために,巨大なクエリを生成してしまい,結果的にパフォーマンスの低下 +を招く場合があります. + +こうした状況に対応するため, ``select_related()`` に ``depth`` 引数を指定す +ると,以下の例のようにリレーションを何「レベル」まで追跡するかを制御できま +す:: + + b = Book.objects.select_related(depth=1).get(id=4) + p = b.author # 追跡済みのリレーション.データベースを操作しません. + c = p.hometown # 未追跡のリレーション.データベースを呼び出します. + +``depth`` 引数は開発版の Django で新たに追加された機能です. + +``extra(select=None, where=None, params=None, tables=None)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +時として, Django のクエリ表記法だけでは複雑な ``WHERE`` 節を容易に表現でき +ない場合があります.こうした特異な場合のために, Django では ``extra()`` +というクエリセット修飾子を提供しています.このメソッドは,クエリセットが +生成する SQL 文中に特定の SQL 節を挿入するためのフックです. + +定義上,これらの拡張照合機能は (直接 SQL コードを書いているため) データベー +スエンジン間の可搬性がありません.また, DRY 則の侵犯でもあります.可能な限 +り使わないようにして下さい. + +``params``, ``select``, ``where``, ``tables`` のいずれかを指定します. +いずれの引数も必須ではありませんが,少なくとも一つは指定せねばなりません. + +``select`` + ``select`` キーワードを使うと, ``SELECT`` 節に追加のフィールドを選択で + きます.この引数は,属性名とその属性値を計算するための SQL 節を対応づけ + た辞書にします. + + 例えば:: + + Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"}) + + のようにすると, ``Entry`` オブジェクトは,エントリの ``pub_date`` が + Jan. 1, 2006 より大きいかどうかを示すブール値の属性 ``is_recent`` を + 持つようになります. + + Django は指定された SQL を直接 ``SELECT`` 文に挿入するので,上の例の + SQL 文は以下のようになります:: + + SELECT blog_entry.*, (pub_date > '2006-01-01') + FROM blog_entry; + + + 次の例はもっと高度です.この例では, ``Blog`` オブジェクトに関連づけら + れている ``Entry`` オブジェクトの個数を表す整数を, ``Blog`` オブジェク + トの ``entry_count`` 属性に持たせるためにサブクエリを実行しています:: + + Blog.objects.extra( + select={ + 'entry_count': 'SELECT COUNT(*) FROM blog_entry ' \ + 'WHERE blog_entry.blog_id = blog_blog.id' + }, + ) + + (上の場合では,クエリの ``FROM`` 節に ``blog_blog`` が入るという事実を + 利用しています.) + + 上の例の場合, SQL は以下のようになります:: + + SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id) + FROM blog_blog; + + ほとんどのデータベースエンジンでは,サブセレクションの周りに丸括弧が必 + 要ですが,Django の ``select`` 節では必要ないということに注意してくださ + い.また, MySQL の一部のバージョンのように,データベースバックエンドに + よってはサブクエリをサポートしないので注意してください. + +``where`` / ``tables`` + 明示的に追加の ``WHERE`` 節を渡す必要がある場合 -- おそらく非明示的な結 + 合を行っている場合 -- には, ``where`` キーワードを使って下さい. + ``tables`` を使えば, SQL の ``FROM`` 節に手動でテーブル名を追加できま + す. + + ``where`` や ``tables`` は,ともに文字列のリストを引数にとります. + ``where`` パラメタの内容は全て,多の検索条件と "AND" で結合されます. + + 例えば:: + + Entry.objects.extra(where=['id IN (3, 4, 5, 20)']) + + は,(大雑把にいって) 以下のような SQL 文に変換されます: + + SELECT * FROM blog_entry WHERE id IN (3, 4, 5, 20); + +``params`` + + 上で説明した ``select`` や ``where`` パラメタでは,標準の Python の文字 + 列プレースホルダ ``'%s'`` を使って,データベースエンジンが自動的にパラ + メタをクオートするよう指示できます. ``params`` 引数には,プレースホル + ダで置き換えられるパラメタのリストを指定します. + + 例えば:: + + Entry.objects.extra(where=['headline=%s'], params=['Lennon']) + + ``select`` や ``where`` の中に直接値を埋め込まず,常に ``params`` を使 + うようにしてください.というのも, ``params`` を使えば,バックエンド固 + 有の方法でパラメタの値を正しくクオートするからです. (例えば引用符文字 + などを正しくエスケープします) + + 悪い例:: + + Entry.objects.extra(where=["headline='Lennon'"]) + + 良い例:: + + Entry.objects.extra(where=['headline=%s'], params=['Lennon']) + + +.. _QuerySet methods that do not return QuerySets: + +QuerySet を返さないクエリセットメソッド +--------------------------------------- + +以下のクエリセットメソッドは,クエリセットを評価して,クエリセット *でない* +値を返します. + +これらのメソッドはキャッシュを使わず (後述の `キャッシュとクエリセット`_ を +参照してください),メソッド呼び出しごとにデータベースにクエリをかけます. + +``get(**kwargs)`` +~~~~~~~~~~~~~~~~~ + +照合パラメタに一致するオブジェクトを返します.照合パラメタは後述の +`フィールドの照合`_ で説明するフォーマットにします. + +複数のオブジェクトが見つかった場合には ``AssertionError`` を送出します. + +指定パラメタに対するオブジェクトが見つからなかった場合には ``DoesNotExist`` +例外を送出します. ``DoesNotExist`` 例外はモデルクラスの属性の一つです. +例えば:: + + Entry.objects.get(id='foo') # raises Entry.DoesNotExist + +``DoesNotExist`` 例外は ``django.core.exceptions.ObjectDoesNotExist`` を継 +承しているので,複数の ``DoesNotExist`` 例外を ``except:`` のターゲットにで +きます.例えば:: + + from django.core.exceptions import ObjectDoesNotExist + try: + e = Entry.objects.get(id=3) + b = Blog.objects.get(id=1) + except ObjectDoesNotExist: + print "Either the entry or blog doesn't exist." + + +``create(**kwargs)`` +~~~~~~~~~~~~~~~~~~~~ + +ワンステップでオブジェクトを生成して保存するための便宜メソッドです。 +すなわち、以下の文:: + + p = Person.objects.create(first_name="Bruce", last_name="Springsteen") + +と、以下の文:: + + p = Person(first_name="Bruce", last_name="Springsteen") + p.save() + +は等価です。 + +``get_or_create(**kwargs)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +kwargs に指定したオブジェクトを照合し、なければ生成するための便宜メソッドで +す。 + + +``(object, created)`` の形式のタプルを返します. ``object`` は取得または作 +成されたオブジェクトであり, ``created`` はブール値で,オブジェクトが新たに +生成されたかどうかを示します. + +このメソッドは,お決まりのコードを書く上でのショートカットとして定義されて +おり,データを取り込むスクリプトを書くときに便利です.例えば:: + + try: + obj = Person.objects.get(first_name='John', last_name='Lennon') + except Person.DoesNotExist: + obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9)) + obj.save() + +このようなコードパターンでは,モデル中のフィールドが増えると手に負えなくな +ります. ``get_or_create()`` を使うと,上のコード例は以下のように書き直せま +す:: + + obj, created = Person.objects.get_or_create(first_name='John', last_name='Lennon', + defaults={'birthday': date(1940, 10, 9)}) + + +``get_or_create()`` に渡されたキーワード引数は, (オプションの引数である +``defaults`` を除いて) 全て ``get()`` の呼び出し時の引数として渡されます. +オブジェクトが見つかった場合, ``get_or_create()`` は見つかったオブジェクト +と ``False`` を返します.オブジェクトが *見つからなかった* 場合,新たに生成 +されたオブジェクトと ``True`` を返します.新たなオブジェクトは以下のアルゴ +リズムで作成されます:: + + defaults = kwargs.pop('defaults', {}) + params = dict([(k, v) for k, v in kwargs.items() if '__' not in k]) + params.update(defaults) + obj = self.model(**params) + obj.save() + +上のコードを日本語で表すなら,まず ``'defaults'`` でないキーワード引数のう +ち,二重アンダースコアを含まないもの (二重アンダースコアはあいまい照合のキー +ワードなので除外します) を使ってパラメタ ``params`` を作成し,必要に応じて +デフォルト値 ``defaults`` で内容を更新して,その結果をモデルクラスを呼び出 +すときのキーワード引数に使います. + +``defaults`` という名前のフィールド名を持っていて, ``get_or_create()`` の +中で厳密照合に使いたければ,以下のように ``'defaults__exact'`` を使います:: + + Foo.objects.get_or_create(defaults__exact='bar', defaults={'defaults': 'baz'}) + +最後に, Django ビューの中で ``get_or_create()`` を使う場合についてひとこと +注意しておきましょう.上で説明したように,主として ``get_or_create()`` が有 +用なのは,データを解析し,該当する既存のデータが存在しない場合に新たなレコー +ドを生成するようなスクリプトを書く場合です.ビューで ``get_or_create()`` を +使いたいのなら,特に理由のない限り ``POST`` リクエスト中で使うようにしましょ +う.一般論として, ``GET`` リクエストの処理中ではデータに影響を及ぼすべきで +はありません.データに副作用をもたらすようなページのリクエストには常に +``POST`` を使うようにしましょう.詳しくは, HTTP 仕様における +`安全なメソッド`_ を参照してください. + +.. _`安全なメソッド`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1 +.. _Safe methods: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1 + + +``count()`` +~~~~~~~~~~~ + +クエリセットに一致するデータベース上のオブジェクトの個数を表す整数を返しま +す. ``count()`` は例外を送出しません. + +例えば:: + + # データベース中のエントリの総数を返します. + Entry.objects.count() + + # ヘッドラインが 'Lennon' を含むエントリの総数を返します. + Entry.objects.filter(headline__contains='Lennon').count() + +``count()`` は背後で ``SELECT COUNT(*)`` を実行するので,単にオブジェクトの +個数を数えたい場合には,全てのレコードを Python オブジェクトとしてロードし +てから ``len()`` を呼び出すのではなく,常に ``count()`` を使うようにしてく +ださい. + +(PostgreSQL や MySQL といった) どのデータベースを使っているかによって,戻り +値が Python の通常の整数型ではなく,長整数になることもあります.これは実装 +上の問題であり,現実的に問題になることはありません. + +``in_bulk(id_list)`` +~~~~~~~~~~~~~~~~~~~~ + +主キーの値のリストを引数にとり,各主キー値とオブジェクトを対応づけた辞書を +返します. + +例えば:: + + >>> Blog.objects.in_bulk([1]) + {1: Beatles Blog} + >>> Blog.objects.in_bulk([1, 2]) + {1: Beatles Blog, 2: Cheddar Talk} + >>> Blog.objects.in_bulk([]) + {} + +``in_bulk()`` に空のリストを渡すと空の辞書を返します. + +``latest(field_name=None)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +日付フィールドである ``field_name`` の値に応じて,テーブル中の最新のオブジェ +クトを返します. + +以下の例では, ``pub_date`` フィールドに応じて,テーブル中の最新の +``Entry`` を返します:: + + Entry.objects.latest('pub_date') + +モデルの ``Meta`` で ``get_latest_by`` を指定している場合, ``latest()`` +の ``field_name`` 引数は省略できます. Django は ``get_latest_by`` に指定し +たフィールドをデフォルト値にします. + +``get()`` と同様, ``latest()`` は指定パラメタに一致するオブジェクトがない +場合に ``DoesNotExist`` を送出します. + +``latest()`` は純粋に利便性と可読性のためだけに存在しています. + +.. _Field lookups: + +フィールドの照合 +---------------- + +フィールドの照合は, SQL の ``WHERE`` 節の中身を決めます.フィールド照合は, +``filter()``, ``exclude()`` および ``get()`` といったクエリセットのメソッド +のキーワード引数として指定します. + +基本的に,照合のキーワード引数名は ``field__lookuptype=value`` のような形 +式をとります (アンダースコアは二重です).例えば:: + + Entry.objects.filter(pub_date__lte='2006-01-01') + +は,(大雑把にいって) 以下のような SQL 文に変換されます:: + + SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01'; + +.. admonition:: フィールド検索のからくり + + Python には,任意の名前と値をもった引数を受け取れる関数を定義する機能が + あり,引数名とその値は実行時に評価されます.くわしい情報は公式の Python + チュートリアルの `キーワード引数`_ を参照してください. + + .. _`キーワード引数`: + http://www.python.jp/doc/release/tut/node6.html#SECTION006720000000000000000 + + +無効なキーワード引数を渡した場合, ``TypeError`` を送出します. + +データベース API では,以下の照合タイプをサポートしています: + +exact +~~~~~ + +厳密な一致です,比較対象の値を ``None`` にすると,SQL における ``NULL`` と +の比較として扱われます (詳しくは isnull_ を参照してください). + +例:: + + Entry.objects.get(id__exact=14) + Entry.objects.get(id__exact=None) + +等価な SQL 文:: + + SELECT ... WHERE id = 14; + SELECT ... WHERE id = NULL; + +iexact +~~~~~~ + +大小文字の区別をしない一致です. + +例:: + + Blog.objects.get(name__iexact='beatles blog') + +等価な SQL 文:: + + SELECT ... WHERE name ILIKE 'beatles blog'; + +この例は, ``'Beatles Blog'``, ``'beatles blog'``, ``'BeAtLes BLoG'`` +などにマッチします. + +contains +~~~~~~~~ + +大小文字を区別する包含テストです. + +例:: + + Entry.objects.get(headline__contains='Lennon') + +等価な SQL 文:: + + SELECT ... WHERE headline LIKE '%Lennon%'; + +この例では, ``'Today Lennon honored'`` というヘッドラインには一致しますが, +``'today lennon honored'`` には一致しません. + +SQLite は大小文字を区別する ``LIKE`` をサポートしないので, ``contains`` は +``icontains`` と同じになります. + +icontains +~~~~~~~~~ + +大小文字を区別しない包含テストです. + +例:: + + Entry.objects.get(headline__icontains='Lennon') + +等価な SQL 文:: + + SELECT ... WHERE headline ILIKE '%Lennon%'; + +gt +~~ + +より大きい値に一致します. + +例:: + + Entry.objects.filter(id__gt=4) + +等価な SQL 文:: + + SELECT ... WHERE id > 4; + +gte +~~~ + +等しいか,より大きい値に一致します. + +lt +~~ + +より少ない値に一致します. + +lte +~~~ + +等しいか,より少ない値に一致します. + +in +~~ + +指定のリストに入っているものに一致します. + +例:: + + Entry.objects.filter(id__in=[1, 3, 4]) + +等価な SQL 文:: + + SELECT ... WHERE id IN (1, 3, 4); + +startswith +~~~~~~~~~~ + +大小文字を区別する starts-with です. + +例:: + + Entry.objects.filter(headline__startswith='Will') + +等価な SQL 文:: + + SELECT ... WHERE headline LIKE 'Will%'; + +SQLite は大小文字を区別する ``LIKE`` をサポートしないので, ``startswith`` +は ``istartswith`` と同じになります. + +istartswith +~~~~~~~~~~~ + +大小文字を区別しない starts-with です. + +例:: + + Entry.objects.filter(headline__istartswith='will') + +等価な SQL 文:: + + SELECT ... WHERE headline ILIKE 'Will%'; + +endswith +~~~~~~~~ + +大小文字を区別する ends-with です. + +例:: + + Entry.objects.filter(headline__endswith='cats') + +等価な SQL 文:: + + SELECT ... WHERE headline LIKE '%cats'; + +SQLite は大小文字を区別する ``LIKE`` をサポートしないので, ``endswith`` +は ``iendswith`` と同じになります. + +iendswith +~~~~~~~~~ + +大小文字を区別しない ends-with です. + +例:: + + Entry.objects.filter(headline__iendswith='will') + +等価な SQL 文:: + + SELECT ... WHERE headline ILIKE '%will' + +range +~~~~~ + +範囲テスト (閉包テスト) です. + +例:: + + start_date = datetime.date(2005, 1, 1) + end_date = datetime.date(2005, 3, 31) + Entry.objects.filter(pub_date__range=(start_date, end_date)) + +等価な SQL 文:: + + SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31'; + +``range`` は日付,数値,文字など,SQL で ``BETWEEN`` を使える場所ならどこで +も使えます. + +year +~~~~ + +date/datetime フィールドにおける, year の厳密一致です. + +例:: + + Entry.objects.filter(pub_date__year=2005) + +等価な SQL 文:: + + SELECT ... WHERE EXTRACT('year' FROM pub_date) = '2005'; + +(厳密な SQL シンタクスはデータベースエンジンによって違います.) + +month +~~~~~ + +date/datetime フィールドにおける, month の厳密一致です. 1 (1月) +から 12 (12 月) までの整数を引数にとります. + +例:: + + Entry.objects.filter(pub_date__month=12) + +等価な SQL 文:: + + SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12'; + +(厳密な SQL シンタクスはデータベースエンジンによって違います.) + +day +~~~ + +date/datetime フィールドにおける, day の厳密一致です. + +例:: + + Entry.objects.filter(pub_date__day=3) + +等価な SQL 文:: + + SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3'; + +(厳密な SQL シンタクスはデータベースエンジンによって違います.) +このクエリ文は,「1 月 3 日」や「7 月 3 日」のように,毎月 3 日,にマッチし +ます. + +isnull +~~~~~~ + +``True`` または ``False`` を引数にとり,それぞれが ``IS NULL`` および +``IS NOT NULL`` に対応しています. + +例:: + + Entry.objects.filter(pub_date__isnull=True) + +等価な SQL 文:: + + SELECT ... WHERE pub_date IS NULL; + +.. admonition:: ``__isnull=True`` vs ``__exact=None`` + + ``__isnull=True`` と ``__exact=None`` には重要な違いがあります. + SQL の定義では ``NULL`` に等しい値は存在しないので, ``__exact=None`` + は *常に* 空の結果セットを返すことになります.一方, ``__isnull`` は, + 指定フィールドに ``NULL`` 値が入っているかどうかを比較演算を行わずに決 + 定します. + +search +~~~~~~ + +全文インデクスを活用した全文検索で、ブール値を返します。このメソッドは +``contains`` に似ていますが、全文インデクスを使うためはるかに高速です。 + +この機能は MySQL でだけ利用可能です。また、全文インデクスを追加するにはデー +タベースを直接操作する必要があります。 + + +.. _Default lookups are exact: + +デフォルトの照合形式は exact +---------------------------- + +照合形式 (lookup type) を指定しない場合,つまりキーワード引数に二重アンダー +スコアが入っていない場合は,照合形式は ``exact`` であるとみなされます. + +例えば,以下の二つの文は等価です:: + + Blog.objects.get(id__exact=14) # 明示的な形式 + Blog.objects.get(id=14) # 暗黙で __exact を表す + +これは ``exact`` 照合がよくある形式であることによる便宜的なものです. + +.. _The pk lookup shortcut: + +pk 照合ショートカット +--------------------- + +利便性のために, Django には ``pk`` という照合形式があります. ``pk`` は +``primary_key`` を表します. + +``Blog`` モデルの例では,主キーは ``id`` フィールドなので,以下の二つの文は +等価になります:: + + Blog.objects.get(id__exact=14) # 明示的な形式 + Blog.objects.get(id=14) # 暗黙で __exact を表す + Blog.objects.get(pk=14) # pk は暗黙で id__exact を表す + +``pk`` は ``__exact`` のクエリにしか使えないわけではありません.どのクエリ +用キーワードも ``pk`` と組み合わせてかまいません. ``pk`` を使ったクエリは, +モデルの主キーに対するクエリになります. + + # id が 1, 4 および 7 のブログエントリを取得する + Blog.objects.filter(pk__in=[1,4,7]) + # id > 14 の全てのブログエントリを取得する + Blog.objects.filter(pk__gt=14) + +``pk`` による検索は join 越しでも行えます. 例えば,以下の二つの文は等価で +す:: + + Entry.objects.filter(blog__id__exact=3) # 明示的な形式 + Entry.objects.filter(blog__id=3) # 暗黙で __exact を表す + Entry.objects.filter(blog__pk=3) # __pk は暗黙で __id__exact を表す + +.. _Lookups that span relationships: + +リレーションをまたいだ照合 +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Django では,背後で自動的に SQL ``JOIN`` を処理し,照合の際にリレーションを +「追跡」する,強力でありながら直感的な手段を提供しています.リレーションを +またぐには,二重アンダースコアを使ってリレーションの張られたフィールドのフィー +ルド名を指定します.リレーション間のスパンは,目的のフィールドに到達するま +でいくらでも連鎖させられます. + +以下の例では, ``name`` が ``'Beatles Blog'`` であるような ``Blog`` の +``Entry`` エントリオブジェクト全てを取得します:: + + Entry.objects.filter(blog__name__exact='Beatles Blog') + +スパンは好きなだけ深く張れます. + +リレーションのスパンは逆方向にも張れます.「逆方向の」リレーションを参照す +るには,モデル名を小文字にした名前を使います. + +以下の例では, ``headline`` に ``'Lennon'`` を含むような ``Entry`` を少なく +とも一つ持つような全ての ``Blog`` オブジェクトを取得します:: + + Blog.objects.filter(entry__headline__contains='Lennon') + +.. _Escaping parenthesis and underscores in LIKE statements: + +LIKE 文におけるパーセントとアンダースコアのエスケープ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``LIKE`` を使う SQL 文になるようなフィールド照合メソッド (``iexact``, +``contains``, ``icontains``, ``startswith``, ``istartswith``, ``endswith``, +``iendswith``) では, ``LIKE`` 文で使われる二つの特殊な文字,すなわちパーセ +ント記号とアンダースコアを自動的にエスケープします. (``LIKE`` 文では,パー +セント記号は任意の複数文字に対するワイルドカードを表し,アンダースコアは任 +意の一文字に対するワイルドカードを表します.) + +この機能によって,照合操作を直感的に行え,データベースの抽象化を守れます. +例えば,パーセント記号を含むようなエントリ全てを取得したければ,以下のよう +にパーセント記号をそのまま使います:: + + Entry.objects.filter(headline__contains='%') + +Django はクオートの処理に気を配ってくれます. SQL は以下のような感じになり +ます:: + + SELECT ... WHERE headline LIKE '%\%%'; + +アンダースコアについても同じようなエスケープを行います.パーセント記号とア +ンダースコアはいずれも透過的に処理されます. + +.. _Caching and QuerySets: + +キャッシュとクエリセット +------------------------ + +データベースへのアクセスを最小限にとどめるため,クエリセット各々にはキャッ +シュがあります.効率的なコードを書く上で,キャッシュのからくりを理解してお +くのは重要なことです. + +クエリセットが新たに生成された時点では,キャッシュは空です.クエリセットを +最初に評価したとき (すなわち,データベースへのクエリが最初に生じたとき), +Django はクエリ結果をクエリセットオブジェクト内のキャッシュに保存し,明示的 +にリクエストした結果だけ (例えば,クエリセットに対してイテレーション操作を +する場合には,結果セットの最初の要素) を返します.それ以後は,クエリセット +を際利用するとキャッシュ済みの結果を返します. + +このキャッシュの挙動をよく覚えておいて下さい.というのも,クエリセットを正 +しく扱わないと,おもわぬところで手を噛まれるはめになるからです.例えば,以 +下の例では二つのクエリセットを作成し,値を評価して,すぐにクエリセットを捨 +ててしまっています:: + + print [e.headline for e in Entry.objects.all()] + print [e.pub_date for e in Entry.objects.all()] + +これはすなわち全く同じデータベースクエリが二度実行され,データベースの負荷 +を倍加させることを示します.また, ``Entry`` は二つのリクエストを処理する間 +にも追加されたり削除されたりする可能性があるため,二つのリストには必ずしも +同じデータベースレコードが入っているとは限りません. + +こうした問題を避けるには,クエリセットを保存して再利用してください:: + + queryset = Poll.objects.all() + print [p.headline for p in queryset] # クエリセットを評価します. + print [p.pub_date for p in queryset] # キャッシュの値を再利用します. + +.. _Comparing objects: + +オブジェクトの比較 +================== + +二つのモデルオブジェクトを比較するには,標準の Python 比較演算子,すなわち +二重等号符: ``==`` を使います.背後では二つのモデルオブジェクト間の主キー値 +が比較されます. + +上の ``Entry`` の例では,以下の二つの文は等価になります:: + + some_entry == other_entry + some_entry.id == other_entry.id + +モデルの主キーが ``id`` という名前でなくても問題はありません.どのような名 +前であれ,比較は常に主キーを使って行われます.例えば,モデルの主キーのフィー +ルド名が ``name`` であれば,以下の二つの文は等価になります:: + + some_obj == other_obj + some_obj.name == other_obj.name + +.. _Complex lookups with Q objects: + +Q オブジェクトを使った複雑な照合 +================================ + +``filter()`` などで複数のキーワード引数を指定してクエリを行うと,各々のキー +ワード引数の表す照合条件は違いに "AND" で結ばれます.より複雑なクエリ (例え +ば ``OR`` を使ったクエリ) を実行する必要がある場合には ``Q`` オブジェクトを +使えます. + +``Q`` オブジェクト (``django.db.models.query.Q``) は,複数のキーワード引数 +をカプセル化するために使われます.キーワード引数は前述の +`フィールドの照合`_ で説明したものと同じです. + +例えば,以下の ``Q`` オブジェクトは単一の ``LIKE`` クエリをカプセル化してい +ます:: + + Q(question__startswith='What') + +``Q`` オブジェクトは ``&`` や ``|`` といった演算子で組み合わせられます.演 +算子で結ばれた二つの ``Q`` オブジェクトは新たな ``Q`` オブジェクトになりま +す. + +例えば,以下の文は二つの ``question__startswith`` クエリを "OR" したものを +表す単一の ``Q`` オブジェクトになります:: + + Q(question__startswith='Who') | Q(question__startswith='What') + + +この ``Q`` オブジェクトは以下の ``WHERE`` 節と同じになります:: + + WHERE question LIKE 'Who%' OR question LIKE 'What%' + +``Q`` オブジェクトを ``&`` と ``|`` で組み合わせれば,好きなだけ複雑なクエ +リ文を作成できます.丸括弧を使ったグルーピングも可能です. + +キーワード引数をとる照合関数 (``filter()``, ``exclude()``, ``get()`` など) +には,複数の ``Q`` を固定引数として (名前なしの引数として) 渡せます.複数の +``Q`` オブジェクトを照合関数に渡した場合,それらは互いに "AND" で結ばれます. +例えば:: + + Poll.objects.get( + Q(question__startswith='Who'), + Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)) + ) + +は,だいたい以下のような SQL になります:: + + SELECT * from polls WHERE question LIKE 'Who%' + AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06') + +照合関数は ``Q`` オブジェクトとキーワード引数を混ぜて使えます.照合関数に渡 +した全ての引数は (キーワード引数も ``Q`` オブジェクトも) 互いに "AND" で結 +ばれます.ただし, ``Q`` を指定する場合はどのキーワード引数よりも前に指定せ +ねばなりませんたとえば:: + + + Poll.objects.get( + Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)), + question__startswith='Who') + +は有効なクエリで,前の例と同じになりますが,以下の文:: + + # INVALID QUERY + Poll.objects.get( + question__startswith='Who', + Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))) + +は無効です. + +`OR lookups examples page`_ の例も参照してください. + +.. _OR lookups examples page: ../models/or_lookups/ + +.. _Related objects: + +リレーション +============ + +モデル内でリレーション (``ForeignKey``, ``OneToOneField``, +``ManyToManyField``) を定義すると,そのモデルのインスタンスはリレーション先 +のオブジェクトにアクセスするための便利な API を持つようになります. + +このドキュメントの冒頭のモデルを例にとると, ``Entry`` オブジェクト ``e`` +は, ``e`` に関連づけられている ``Blog`` オブジェクトに ``blog`` という属性 +を使って ``e.blog`` のようにアクセスできます. + +(舞台裏では,この機能は Python の `デスクリプタ`_ を使って実装されています. +だからどうだというわけではありませんが,興味のある人のためにここで指摘して +おきます.) + +Django はまた,リレーションの「相手側」へのアクセス API,すなわちリレーショ +ンを張られた側からリレーションを張った側のモデルへのリンクも作成します.例 +えば, ``Blog`` オブジェクト ``b`` は,リレーションを張った全ての ``Entry`` +オブジェクトのリストに ``entry_set`` 属性を使って ``b.entry_set.all()`` の +ようにアクセスできます. + +この節での例は,全て冒頭に示した ``Blog`` ``Blog``, ``Author``, ``Entry`` +のモデルを使っています. + +.. _`デスクリプタ`: http://users.rcn.com/python/download/Descriptor.htm +.. _descriptors: http://users.rcn.com/python/download/Descriptor.htm + +.. _One-to-many relationships: + +一対多のリレーション +-------------------- + +.. _Forward: + +順方向 +~~~~~~ + +モデルに ``ForeignKey`` フィールドがある場合,そのモデルのインスタンスは, +単に属性を使ってリレーション先 (外部) のオブジェクトを参照できます. + +例:: + + e = Entry.objects.get(id=2) + e.blog # リレーション先の Blog オブジェクトを返します. + +外部キー属性の値は取得 (get) も設定 (set) もできます.当然ながら,外部キー +への変更は ``save()`` を呼び出すまでデータベースに反映されません. + +例:: + + e = Entry.objects.get(id=2) + e.blog = some_blog + e.save() + +``ForeignKey`` フィールドに ``null=True`` が設定されていた場合 (``NULL`` 値 +を許している場合),以下の例のように ``None`` を代入できます:: + + e = Entry.objects.get(id=2) + e.blog = None + e.save() # "UPDATE blog_entry SET blog_id = NULL ...;" + +一対多のリレーションにおける順方向のアクセスは,リレーション先のオブジェク +トに最初にアクセスした際にキャッシュされます.それ以降のアクセスでは,同じ +オブジェクトインスタンスの外部キーへのアクセスはキャッシュされた値を返しま +す.例えば:: + + e = Entry.objects.get(id=2) + print e.blog # データベースを検索して,関連づけられた Blog を返します. + print e.blog # データベースは検索せず,キャッシュを使います. + +クエリセットのメソッド ``select_related()`` を使うと,一対多のリレーション +のリレーション先オブジェクト全てをあらかじめ再帰的にキャッシュに取り込みま +す.例えば:: + + e = Entry.objects.select_related().get(id=2) + print e.blog # Doesn't hit the database; uses cached version. + print e.blog # Doesn't hit the database; uses cached version. + +``select_related()`` のドキュメントは,前述の「 新たなクエリセットを返すク +エリセットメソッド」の節にあります. + +.. _Backward: + +逆方向 +~~~~~~ + +あるモデルが ``ForeignKey`` で別のモデルにリレーションを張っている場合,リ +レーションを張られた側のモデルのインスタンスは,リレーションを張った側のモ +デルの全てのインスタンスを返すマネジャにアクセスできるようになります.リレー +ションを張っている側のモデル名を全て小文字にしたものを ``FOO`` とすると,マ +ネジャの名前のデフォルト値は ``FOO_set`` になります.このマネジャはクエリセッ +トを返します.クエリセットには前述の「オブジェクトの取得」の節で説明したフィ +ルタや操作を行えます. + +例:: + + b = Blog.objects.get(id=1) + b.entry_set.all() # Blog に関連づけられた全ての Entry を返します. + + # b.entry_set はクエリセットを返すマネジャです. + b.entry_set.filter(headline__contains='Lennon') + b.entry_set.count() + +``ForeignKey`` を定義するときに ``related_name`` パラメタを設定しておくと, +``FOO_set`` の名前をオーバライドできます.例えば, ``Entry`` モデルの定義を +``blog = ForeignKey(Blog, related_name='entries')`` のように改めると,上の +コード例は以下のようになります:: + + b = Blog.objects.get(id=1) + b.entries.all() # Blog に関連づけられた全ての Entry を返します. + + # b.entries はクエリセットを返すマネジャです. + b.entries.filter(headline__contains='Lennon') + b.entries.count() + +``ForeignKey`` のマネジャへの逆のアクセスはできません. ``ForeignKey`` はイ +ンスタンスとしてアクセスせねばなりません.例えば:: + + + # AttributeError: "Manager must be accessed via instance" を送出します. + Blog.entry_set + +前述の「オブジェクトの取得」で説明したクエリセットのメソッドに加えて, +``ForeignKey`` を介したマネジャは以下の追加のメソッドを備えています: + + * ``add(obj1, obj2, ...)``: 指定のモデルオブジェクトをリレーション先オ + ブジェクトのセットに加えます. + + 例:: + + b = Blog.objects.get(id=1) + e = Entry.objects.get(id=234) + b.entry_set.add(e) # Associates Entry e with Blog b. + + * ``create(**kwargs)``: 新たなオブジェクトを作成し,保存して,リレーショ + ン先オブジェクトのセットに加えます.作成したオブジェクトを返します. + + 例:: + + b = Blog.objects.get(id=1) + e = b.entry_set.create(headline='Hello', body_text='Hi', + pub_date=datetime.date(2005, 1, 1)) + # 自動的に save() されるので, e.save() を呼ぶ必要はありません. + + これは以下の操作と同じです (ただし前者の方が簡潔です):: + + b = Blog.objects.get(id=1) + e = Entry(blog=b, headline='Hello', body_text='Hi', + pub_date=datetime.date(2005, 1, 1)) + e.save() + + モデルからオブジェクトを作成するときに,リレーションを定義するための + キーワード引数を必要としないことに注意して下さい.上の例では, + ``create()`` に ``blog`` パラメタを渡していません. Django は + ``Entry`` オブジェクトの ``blog`` フィールドの値が ``b`` であることを + 自分で判別します. + + * ``remove(obj1, obj2, ...)``: リレーション先オブジェクトのセットから, + 指定のオブジェクトを除去します. + + 例:: + + b = Blog.objects.get(id=1) + e = Entry.objects.get(id=234) + b.entry_set.remove(e) # Blog b から Entry e を除去します. + + データベースの一貫性を壊さないようにするため,このメソッドは + ``null=True`` である ``ForeignKey`` オブジェクトでしか使えません.リ + レーション先のフィールドを ``None`` (``NULL``) にできない場合,あるオ + ブジェクトを削除しようとしたときに,必ず何らかの別のオブジェクトに追 + 加せねばならなくなるからです.上の例では, ``b.entry_set()`` から + ``e`` を除去する操作は ``e.blog = None`` と同じになり, 外部キー + ``blog`` が ``null=True`` でないために無効な操作になります. + + * ``clear()``: リレーション先オブジェクトのセットから全てのオブジェクト + を除去します. + + 例:: + + b = Blog.objects.get(id=1) + b.entry_set.clear() + + リレーション先のオブジェクト全てを削除するわけではありません.単にリ + レーションを解除するだけです. + + ``remove()`` や ``clear()`` と同様, ``null=True`` であるような外部キー + でしか使えません. + +リレーション先セットのメンバを一括で代入するには,イテレーション可能オブジェ +クトを代入します.例えば:: + + b = Blog.objects.get(id=1) + b.entry_set = [e1, e2] + +``clear()`` メソッドを利用できる場合,イテレーション可能オブジェクト (上の +例ではリスト) からオブジェクトを ``entry_set`` に追加する前に,代入先のセッ +トに既に存在するオブジェクトを全て除去します. ``clear()`` メソッドを利用 +*できない* 場合,既に存在するオブジェクトを削除せず,単にイテレーション可能 +オブジェクト上の全てのオブジェクトを追加します. + +この節で説明した「逆方向の」操作は,いずれもデータベースを即時変更します. +操作結果は追加,新規作成,削除といった操作を行う度に即座に自動的にデータベー +スに保存されます. + +.. _Many-to-many relationships: + +多対多のリレーション +-------------------- + +多対多のリレーションの場合,リレーションの関係にあるモデルの一方は,互いに +もう一方にアクセスするための自動 API を獲得します.この API は一対多のリレー +ションにおける「逆方向の」参照のように動作します.前述の `逆方向`_ を参照し +てください. + +一対多のリレーションとの唯一の違いは,属性の名前づけ規則です. +``ManyToManyField`` を定義した側のモデルはフィールド名をそのまま使いますが, +「反対側の」モデルでは,相手のモデルのモデル名を小文字にして, ``'_set'`` +を追加したもの (一対多のリレーションにおける逆方向の参照と同じ) になります. + +例を使って説明した方が理解しやすいでしょう:: + + e = Entry.objects.get(id=3) + e.authors.all() # Entry の全ての Author オブジェクトを返します. + e.authors.count() + e.authors.filter(name__contains='John') + + a = Author.objects.get(id=5) + a.entry_set.all() # Author の全ての Entry オブジェクトを返します. + +``ForeignKey`` と同様, ``ManyToManyField`` には ``related_name`` パラメタ +を指定できます. 上の例で, ``Entry`` の ``ManyToManyField`` に +``related_name='entries'`` を指定していた場合, ``Author`` インスタンスは +``entry_set`` ではなく ``entries`` という属性を持つようになります. + + +.. _One-to-one relationships: + +一対一のリレーション +-------------------- + +一対一のリレーションのセマンティクスはまもなく変更されるので,使わないよう +に勧めます. + +.. _How are the backward relationships possible?: + +リレーションの後方参照はどうやって実現されているのか +---------------------------------------------------- + +他のオブジェクトリレーショナルマッパでは,双方向からリレーションを定義せね +ばなりません. Django の開発者たちはこれを DRY 則 (Don't Repeat Yourself) +の侵犯だと考えたため, Django では片方だけでリレーションを定義すればよいよ +うにしています. + +しかし,なぜあるモデルクラスが,自分に対してリレーションを張っているモデル +クラスのことを,そのクラスがロードされる前に検知できるのでしょうか? + +答えは ``INSTALLED_APPS`` 設定にあります.最初にモデルをロードした時に, +Django は ``INSTALLED_APPS`` の全てのモデルを走査して,必要に応じて後方参照 +をメモリ中に作成します. ``INSTALLED_APPS`` の本質的な機能の一つは, Django +にモデルドメインの全体像を知らせることなのです. + +.. _Queries over related objects: + +リレーション先オブジェクトを使ったクエリ +---------------------------------------- + +リレーション先のオブジェクトを照合条件に含むクエリは、通常の値のフィールド +の入ったくえりと同じような規則に従います。クエリにマッチ条件として値を指定 +する場合、オブジェクトのインスタンス自体か、オブジェクトの主キー値のいずれ +かを使えます。 + +例えば、 ``id=5`` であるようなBlog オブジェクト ``b`` に対しては、以下の三 +つのクエリはすべて等価になります:: + + Entry.objects.filter(blog=b) # オブジェクトインスタンスを使ったクエリ + Entry.objects.filter(blog=b.id) # インスタンスの id を使ったクエリ + Entry.objects.filter(blog=5) # id を直接使ったクエリ + +.. _Deleting objects: + +オブジェクトの削除 +================== + +削除用のメソッドには,便宜的に ``delete()`` という名前が付いてます.このメ +ソッドはオブジェクトをただちに削除し,戻り値を返しません.例えば:: + + e.delete() + +複数のオブジェクトの一斉削除も可能です. ``QuerySet`` には ``delete()`` +メソッドがあり, ``QuerySet`` の全てのメンバを削除します. + +例えば, ``pub_date`` が 2005 年の ``Entry`` オブジェクトを全て削除するには +以下のようにします:: + + Entry.objects.filter(pub_date__year=2005).delete() + +Django は,オブジェクトを削除する際に,SQLでいう ``ON DELETE CASCADE`` 制約 +をエミュレートします.すなわち,削除対象のオブジェクトを指すような外部キー +を持つ全てのオブジェクトも同時に削除されるのです.:: + + b = Blog.objects.get(pk=1) + # 次の命令は, Blog と Blog を指す Entry 全てを削除してしまいます. + b.delete() + + +``delete()`` は ``QuerySet`` のメソッドにすぎず, ``Manager`` 自体には公開 +されていないので注意してください.これは誤って ``Entry.objects.delete()`` +を実行して *全ての* エントリを削除してしまわないようにするための安全機構で +す.本当に全てのオブジェクトを削除 *したい* のなら,以下のように明示的に全 +てのオブジェクトを表すクエリセットをリクエストしてください:: + + Entry.objects.all().delete() + + +.. _Extra instance methods: + +追加のインスタンスメソッド +========================== + +``save()``, ``delete()`` に加えて,モデルオブジェクトは以下のいずれか,あるい +は全てのメソッドを持つことがあります: + +get_FOO_display() +----------------- + +``choices`` セットを持つ全てのフィールドについて,オブジェクトは +``get_FOO_display()`` メソッドを持ちます. ``FOO`` はフィールド名です.この +メソッドは,「人間可読な」フィールド名を返します.例えば,以下のモデル:: + + GENDER_CHOICES = ( + ('M', 'Male'), + ('F', 'Female'), + ) + class Person(models.Model): + name = models.CharField(maxlength=20) + gender = models.CharField(maxlength=1, choices=GENDER_CHOICES) + +では,各 ``Person`` インスタンスは ``get_gender_display()`` メソッド +を持ちます:: + + >>> p = Person(name='John', gender='M') + >>> p.save() + >>> p.gender + 'M' + >>> p.get_gender_display() + 'Male' + +get_next_by_FOO(\**kwargs) and get_previous_by_FOO(\**kwargs) +------------------------------------------------------------- + +``null=True`` であるような ``DateField`` および ``DateTimeField`` フィール +ドについて,オブジェクトは ``get_next_by_FOO()`` および +``get_previous_by_FOO()`` メソッドを持ちます. ``FOO`` はフィールド名です. +このメソッドは該当の日付フィールドに応じて前のオブジェクトや次のオブジェク +トを返します.適切なオブジェクトがなければ ``DoesNotExist`` を送出します. + +これらのメソッドはいずれもオプションのキーワード引数をとります.引数は +前述の「フィールド検索」で解説した形式にします. + +同じ日付値を持つオブジェクトがある場合,このメソッドは ID を使ったチェック +にフォールバックします.これにより,レコードがスキップしたり重複したりしな +いことが保証されています.完全なコードの例は `照合 API のサンプルモデル`_ +を参照してください. + +.. _`照合 API のサンプルモデル`: ../models/lookup/ +.. _lookup API sample model: ../models/lookup/ + +get_FOO_filename() +------------------ + +各 ``FileField`` につき,オブジェクトは ``get_FOO_filename()`` メソッドを持 +ちます. ``FOO`` はフィールド名です.このメソッドは, ``MEDIA_ROOT`` の設定 +に基づいてファイルのファイルシステム上での完全なパスを返します. + +``ImageField`` は技術的に ``FileField`` のサブクラスであるため, +``ImageField`` のフィールドを持つ全てのモデルはこのメソッドを使えます. + +get_FOO_url() +------------- + +各 ``FileField`` につき,オブジェクトは ``get_FOO_url()`` メソッドを持ちま +す. ``FOO`` はフィールド名です.このメソッドは, ``MEDIA_URL`` の設定に基づ +いてファイルの完全な URL を返します.フィールドの値が空の場合,空文字列を返 +します. + +get_FOO_size() +-------------- + +各 ``FileField`` につき,オブジェクトは ``get_FOO_filename()`` メソッドを持 +ちます. ``FOO`` はフィールド名です.このフィールドはファイルのサイズをバイ +トを単位として返します (背後では ``os.path.getsize`` を使っています). + +save_FOO_file(filename, raw_contents) +------------------------------------- + +各 ``FileField`` につき,オブジェクトは ``get_FOO_filename()`` メソッドを持 +ちます. ``FOO`` はフィールド名です.このメソッドは指定のファイルを指定のファ +イル名でファイルシステムに保存します.指定されたファイル名のファイルがすで +に存在する場合, Django は同名のファイルが見つからなくなるまでファイル名の +末尾 (かつ,拡張子よりも前) にアンダースコアを追加してゆきます. + +get_FOO_height() and get_FOO_width() +------------------------------------ + +各 ``ImageField`` につき,オブジェクトは ``get_FOO_width()`` および +``get_FOO_width()`` メソッドを持ちます. ``FOO`` はフィールド名です.このメ +ソッドは画像の高さ (や幅) をピクセルを単位とする整数で返します. + +.. _Shortcuts: + +ショートカット用の関数 +====================== + +ビューを開発していると,データベース API を操作するためのイディオムがいくつ +もあることに気づくはずです. Django はこうしたイディオムをショートカット関 +数として定義し,ビュー内の処理をすっきりと書けるようにしています. + +get_object_or_404() +------------------- + +よく使われるイディオムの一つは, ``get()`` を呼び出し,オブジェクトが存在し +ないときには ``Http404`` を送出するというものです. ``get_object_or_404()`` +はこの処理を関数にしたものです. ``get_object_or_404()`` は Django モデルを +第一引数に取り,さらに任意のキーワード引数を取れます.キーワード引数はモデ +ルのマネジャの ``get()`` 関数に渡されます.オブジェクトが存在しなければ +``Http404`` を送出します:: + + # 主キーが 3 のエントリを取得する + e = get_object_or_404(Entry, pk=3) + +このショートカット関数をモデルに渡す場合,背後で ``get()`` クエリを受けるの +はデフォルトのマネジャです.デフォルト以外のマネジャを使いたい場合や,モデ +ルにリレーションを張っているオブジェクトのリストを得たい場合には,以下の例 +のように ``get_object_or_404()`` にマネジャオブジェクトを直接指定してくださ +い:: + + # Blog モデルのインスタンス `e` に関連づけられている,名前が 'Fred' の + # 'Fred' の Author インスタンスを取得する + a = get_object_or_404(e.authors, name='Fred') + + # カスタムマネジャ 'recent_entries' を使って,主キーが 3 のエントリを + # 検索する + e = get_object_or_404(Entry.recent_entries, pk=3) + +get_list_or_404() +----------------- + +``get_list_or_404`` の動作は ``get_object_or_404()`` とほとんど同じですが, +``get()`` の代わりに ``filter()`` を使い,リストが空の場合に ``Http404`` を +送出します. + + +.. _Falling back to raw SQL: + +生 SQL へのフォールバック +========================= + +Django のデータベースマッパで扱うには複雑すぎる SQL 文を書かねばならないよ +うな場合には,生の SQL 文実行モードを使えます. + +生 raw-SQL 文実行モードの使い方としてお勧めなのは,そのようなクエリ文を実行 +するモデルのカスタムメソッドやカスタムマネジャのメソッドを実装するというも +のです. Django はモデルレイヤでデータベースクエリを記述するように +*要求してはいません* が,このアプローチをとることで,データアクセスのための +ロジックを一箇所にまとめられるので,コード組織化の観点からスマートになりま +す.詳しい説明は `カスタム SQL 文の実行`_ を参照してください. + +最後に, Django のデータベースレイヤは単にデータベースへの一つのインタフェー +スに過ぎないということに注意しておきましょう.データベースには他のツールや +プログラム言語,データベースフレームワークを介してアクセスできます.データ +ベースについて Django 固有の何かがあるわけではないのです. + +.. _`カスタム SQL 文の実行`: ../model_api/#executing-custom-sql +.. _Executing custom SQL: ../model_api/#executing-custom-sql diff --git a/design_philosophies.txt b/design_philosophies.txt new file mode 100644 index 0000000..9311091 --- /dev/null +++ b/design_philosophies.txt @@ -0,0 +1,362 @@ +=================== +Django の設計思想 +=================== + +:revision-up-to: 4805 (release 0.96) + +このドキュメントでは, Django の開発者たちがフレームワークの構築に取り入れ +ている根本的な設計思想についていくつか解説します.それによって, Django の +これまでの経緯に説明を与えつつ,将来への指針にしたいと思います. + +.. _Overall: + +全体的な設計思想 +================ + +.. _Loose coupling: + +ルースカップリング +------------------ + +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 開発を信じられないくらいに迅速化し +ます. + +.. _Don't repeat yourself (DRY): + +DRY (Don't repeat yourself) 則 +------------------------------- + +個別のコンセプトやデータは,一つの,ただ一つの場所に置かねばなりません.冗 +長は悪,正規化は善です. + +こうした理由から,フレームワークは可能な限り小さくせねばなりません. + +.. _Explicit is better than implicit: + +暗示的より明示的に +------------------ + +`Python のコア原理`_ の一つでもあるこの思想により, Django は「黒魔術的」で +あってはなりません.どうしても必要な理由がないかぎり魔術的な処理を取り入れ +てはなりません.魔術的な処理を取り入れる価値があるのは,他の方法では実現し +得ない多大な利便性が生まれ,かつその機能の使い方を学ぼうとする開発者が混乱 +しないような形で実装できる場合だけです. + +.. _`Python のコア原理`: http://www.python.jp/Zope/articles/misc/zen +.. _`core Python principle`: http://www.python.org/doc/Humor.html#zen + +.. _Consistency: + +一貫性 +------ + +フレームワークは全ての水準で一貫性を保たねばなりません.この一貫性は低水準 +(Python のコーディングスタイル) から高水準 (Djangoの「使用感:experience」) +にいたる全てにあてはまります. + +.. _Models: + +モデル +====== + +.. Explicit is better than implicit: + +暗示的より明示的に +------------------ + +データの挙動をフィールド名だけから決定してはなりません.さもなければ必要以 +上にシステムを熟知せねばならず,エラーのもとになります. +その代り,データの挙動はキーワード引数や,場合によってはフィールドのタイプ +に基づいて決定します. + +.. _Include all relevant domain logic: + +関連領域のロジックは全てまとめる +-------------------------------- + +モデルは「オブジェクト」としての様々な側面をカプセル化し,いわゆる +Martin Fowler の `アクティブレコード`_ デザインパターンに従わねばなりません. + +モデル固有の admin オプションをモデル自身に取り込んでいるのはこのためです. +モデルに関係するデータはモデルの *中に* 保存すべきなのです. + +.. _`アクティブレコード`: http://www.martinfowler.com/eaaCatalog/activeRecord.html +.. _`Active Record`: http://www.martinfowler.com/eaaCatalog/activeRecord.html + +.. _Database API: + +データベース API +================ + +データベース API の主要な目的を示します: + +.. _SQL efficiency: + +SQL の効率を考慮 +---------------- + +SQL 文の実行は可能な限り少なくし,内部的に最適化せねばなりません. + +データの保存をフレームワークに背後で暗黙のうちに行わせず,開発者に +``save()`` を明示的に呼び出させるのはこのためです. + +また, ``QuerySet`` の ``select_related()`` メソッドが存在するのもこのため +です. ``select_related`` は「関連する全てのオブジェクト」を select すると +いう,よくあるケースに対してパフォーマンス向上をもたらします. + +.. _Terse, powerful syntax: + +むだのない強力な構文 +---------------------- + +データベース API は,高機能かつ表現性に富み,可能な限り小さな構文でなければ +なりません. API は他のモジュールやヘルパオブジェクトに依存してはなりません. + +joiin は必要に応じて舞台裏で自動的に行われねばなりません. + +システム全体にわたって,各オブジェクトは自分とリレーションにあるオブジェク +トにアクセスできねばなりません.リレーションの追跡は双方向に行われねばなり +ません. + +.. _Option to drop into raw SQL easily, when needed: + +必要なら生の SQL も簡単に使えるように +------------------------------------- + +データベース API の設計では,ショートカットとして便利でありながらも,必ずし +も全ての機能に手がとどかなくてもよいということを理解していなければなりませ +ん.フレームワークは SQL 文全体,あるいは ``WHERE`` 節だけのカスタムの SQL +を簡単に書けるようにせねばなりません. + +.. _URL design: + +URL の設計 +========== + +.. Loose coupling: + +ルースカップリング +------------------ + +Django アプリケーションでは, URL を特定の Python コードとカップリングして +はなりません. URL と Python 関数名の関連づけは,間違っており,美しくありま +せん. + +同様に, Django の URL システムは同じアプリケーションを異なるコンテキストで +使えねばなりません.例えば,あるサイトで記事 (story) にアクセスするのに +``/stories/`` を使っていたとしても,別のところで ``/news/`` という URL で記 +事にアクセスできねばなりません. + +.. _Infinite flexibility: + +無限の柔軟性 +------------ + +URL には可能な限り柔軟性をもたせねばなりません.考えられるいかなる URL 設計 +も使えねばなりません. + +.. _Encourage best practices: + +王道を進みやすく +---------------- + +フレームワークはすっきりとした URL 設計を (汚い設計よりも) 簡単におこなえね +ばなりません. + +Web ページの URL にファイル拡張子を使うのはさけねばなりません. + +URL にカンマを入れる Vignette スタイルは厳しく禁じねばなりません. + +.. _Definitive URLs: + +URL ははっきりと +---------------- + +技術的にあh, ``foo.com/bar`` と ``foo.com/bar/`` は別個の URL であり,検索 +エンジンロボット (や Web トラフィック解析ツール) はこれらのページを別々のも +のとして扱わねばなりません. Django は URL を「正規化」して,検索エンジンロ +ボットを混乱させないようにせねばなりません. + +これは ``APPEND_SLASH`` 設定の根底にある考えです. + +.. _Template system: + +テンプレートシステム +==================== + +.. _Separate logic from presentation: + +プレゼンテーションとロジックの分離 +---------------------------------- + +私達は,テンプレートシステムはプレゼンテーションとプレゼンテーション関係の +ロジックを制御するためのツールであり,それ以上のものではないと考えています. +その本分をこえた機能をテンプレートシステムに求めるべきではありません. + +何もかもテンプレートに押し込みたかったのなら,今ごろ PHP を使っていたでしょ +う.かつてそうしていましたが,今はやめ,そこから学んだのです. + +.. _Discourage redundancy: + +冗長さを防ぐ +------------ + +大多数の動的な Web サイトでは,ヘッダやフッタ,ナビゲーションバーといった部 +分のデザインをサイト全体で共通にしています. Django テンプレートシステムは, +こうしたサイトの構成要素を一箇所に保存しやすくし,コードの複製を無くさねば +なりません. + +これは `テンプレートの継承`_ の根底にある考え方です. + +.. _`テンプレートの継承`: ../templates/#template-inheritance +.. _template inheritance: ../templates/#template-inheritance + +.. _Be decoupled from HTML: + +HTML に縛られない +----------------- + +HTML だけを出力するようにテンプレートシステムを設計すべきではありません. +他のテキストベース形式や単なる平文テキストの生成もうまく実現できねばなりま +せん. + +.. _XML should not be used for template languages: + +XML をテンプレート言語に使わない +-------------------------------- + +テンプレートのパージングに XML エンジンを使うと,テンプレート編集における +人為エラーという新たな問題に直面します.それに,テンプレート処理に受け入れ +がたいオーバヘッドを被ることになります. + +.. _Assume designer competence: + +ページデザイナの有能さを前提にする +---------------------------------- + +必ずしも Dreamweaver のような WYSIWYG エディタでうまく表示できるように +テンプレートシステムを設計する必要はありません.そのような要求は制限が +厳しすぎ,本来あるべきすっきりした構文を実現できなくなります. Django では +直接 HTML を編集する作業に慣れたテンプレート作者を想定しています. + +.. _Treat whitespace obviously: + +空白の扱いはわかりやすく +------------------------ + +テンプレートシステムは魔法的な空白の処理を行ってはなりません.テンプレート +に空白をいれた場合,システムは空白部分を普通のテキストと同じように扱う, +すなわちそのまま表示せねばなりません.逆に,テンプレートタグにない空白を +表示すべきでもありません. + +.. _Don't invent a programming language: + +プログラミング言語を作り直さない +-------------------------------- + +テンプレートシステムでは,以下の機能を意図的に使えないようにしています: + + * 変数の代入 + * 高度なロジック + +テンプレートシステムが目的とするのは新たなプログラミング言語の発明では +ありません.目的は,分岐やループといった,プレゼンテーションまわりの判定で +必須のプログラム機能の提供だけです. + +Django テンプレートシステムでは,最もテンプレートを良く書くのは +*プログラマ* ではなく *デザイナ* とみなしており, Python の知識を前提には +していません. + +.. _Safety and security: + +安全性とセキュリティ +-------------------- + +テンプレートシステムは,使い始めの時点で,外部コマンドの実行やデータベース +レコードの削除といった悪意あるコードを取り込めないようになっていなければなり +ません. + +これは,テンプレートシステムが任意の Python コードにアクセスできるように +してはならないもう一つの理由でもあります. + +.. _Extensibility: + +拡張性 +------ + +テンプレートシステムは,高度なテンプレート作者によるテクノロジの拡張に配慮 +せねばなりません. + +これはカスタムテンプレートタグやフィルタの根底にある哲学です. + +.. _Views: + +ビュー +====== + +.. _Simplicity: + +簡潔性 +------ + +ビューは Python の関数として可能な限りシンプルに書きます.開発者は関数でで +きることを実現するために,クラスのインスタンスを生成する必要はありません. + +.. _Use request objects: + +リクエストオブジェクトの利用 +----------------------------- + +ビューはリクエストオブジェクトにアクセスします.リクエストオブジェクトとは, +現在のリクエストに関するメタデータを入れるオブジェクトです.ビューはこのオ +ブジェクトをグローバル変数経由でアクセスするのではなく,引数として直接受け +取るようにすべきです.それにより,「偽の」リクエストオブジェクトを渡してビュー +を簡単かつクリーンにテストできるようになります. + +.. Loose coupling: + +ルースカップリング +------------------ + +ビューは開発者がどのテンプレートシステムを使うか関知すべきではなく,使って +いるテンプレートシステムがいくつかすら関知すべきではありません. + +.. _Designate between GET and POST: + +GET と POST の使い分け +---------------------- + +GET と POST は全く違います.開発者はこれらを明示的に使い分けねばなりません. +フレームワークはデータの GET と POST を容易に判別できねばなりません. diff --git a/distributions.txt b/distributions.txt new file mode 100644 index 0000000..9cce398 --- /dev/null +++ b/distributions.txt @@ -0,0 +1,89 @@ +================================================== +サードパーティによる Django ディストリビューション +================================================== + +:revision-up-to: 4805 (release 0.96) + +最近,いくつかのサードパーティのディストリビューションプロバイダが,パッケー +ジ管理システムに Django を含めるようになりました.パッケージ管理システムを +使うと,Django の動作に必要な依存関係のあるコンポーネント (データベースアダ +プタなど) を自動的にインストールできるため,インストールやアップグレードの作業が大幅に簡単化されます. + +通常,サードパーティのディストリビューションパッケージは最近の安定版リリー +スの Django をもとに作成されます.このため,開発版の Django を使いたければ, +`開発バージョンのインストール <../install/#installing-the-development-version>`_ +の説明に従って,Subversion リポジトリから取得する必要があるでしょう. + +.. _installing the development version: ../install/#installing-the-development-version + +.. _Linux distributions: + +Linux ディストリビューション +============================ + +Debian +------ + +`Debian GNU/Linux`_ では, +`パッケージ版の Django `_ +を利用できます.インストールは "testing" および "unstable" のどちらのリポジ +トリからでも行えます. ``apt-get install python-django`` と入力します. + +Debian 向けのパッケージをインストールする場合, ``apt`` はデータベースアダ +プタのインストールを勧めてくるでしょう. Django と組み合わせて使いたいデー +タベース向けのアダプタを選んでインストールしてください. + +.. _Debian GNU/Linux: http://www.debian.org/ +.. _packaged version of Django: http://packages.debian.org/testing/python/python-django + +Ubuntu +------ + +Debian の ``python-django`` パッケージは `Ubuntu Linux`_ でも利用でき, +Ubuntu 7.04 ("Feisty Fawn") の "universe" リポジトリに入っています. +`現行の Ubuntu パッケージ `_ +は Django 0.95.1 ベースで, Debian と同じ方法でインストールできます. + +.. _Ubuntu Linux: http://www.ubuntu.com/ +.. _current Ubuntu package: http://packages.ubuntu.com/feisty/python/python-django + +Fedora +------ + +`Fedora Linux`_ 向けの Django ビルドは "Fedora Extras" リポジトリに入ってい +ます. +`現行の Fedora パッケージ `_ +は0.95.1 に基づいており,インストールするには ``yum install Django`` とタイ +プします. + +.. _Fedora Linux: http://fedora.redhat.com/ +.. _current Fedora package: http://fedoraproject.org/extras/6/i386/repodata/repoview/Django-0-0.95.1-1.fc6.html + +Gentoo +------ + +`Gentoo Linux`_ 向けの Django ビルドは 0.95.1 に基づいています. +`現行の Gentoo ビルド `_ +をインストールするには, ``emerge Django`` とタイプします. + +.. _Gentoo Linux: http://www.gentoo.org/ +.. _current Gentoo build: http://packages.gentoo.org/packages/?category=dev-python;name=django + +.. _For distributors: + +ディストリビューション作成者のための情報 +======================================== + +ディストリビューションパッケージを作成したいと考えているなら,喜んでお手伝 +いします.まずは +`django-developers メーリングリスト `_ +に入って自己紹介してください. + +また,ディストリビューション作成者は, +`django-announce メーリングリスト `_ +にも入っておくよう勧めます.このメーリングリストは (とても) 流量の少ないメー +リングリストで, Django の新しいリリースやバグフィクスに関するアナウンスが +流れます. + +.. _django-developers mailing list: http://groups.google.com/group/django-developers/ +.. _django-announce mailing list: http://groups.google.com/group/django-announce/ diff --git a/django-admin.txt b/django-admin.txt new file mode 100644 index 0000000..fd3fa0c --- /dev/null +++ b/django-admin.txt @@ -0,0 +1,578 @@ +============================ +django-admin.py と manage.py +============================ + +:revision-up-to: 4805 (release 0.96) + +``django-admin.py`` は Django の管理タスクを行うためのコマンドライン +ユーティリティです.このドキュメントでは ``django-admin.py`` の全ての +機能について説明します. + +また,各 Django プロジェクトには ``manage.py`` が自動的に生成されます. +``manage.py`` は ``django-admin.py`` に対する薄いラッパで, +``django-admin.py`` に仕事を引き渡す前に以下の二つの処理を行います: + + * プロジェクトのパッケージを ``sys.path`` に追加します. + + * ``DJANGO_SETTINGS_MODULE`` 環境変数がプロジェクトの + ``settings.py`` を指すように設定します. + +Django を ``setup.py`` ユーティリティでインストールしていれば, +``django-admin.py`` スクリプトはシステムパス上にあるはずです.システム +パス上にない場合, Python インストールディレクトリ上の +``site-packages/django/bin`` を探せば見つかるでしょう. +``/usr/local/bin`` のようなパス上のどこかにシンボリックリンクを張って +おくように勧めます. + +Windows を使っていて,シンボリックリンクを張れない場合には,パスの通った場 +所に ``django-admin.py`` をコピーするか, ``PATH`` の設定値を ( +``マイコンピュータ(右クリック)`` - ``プロパティ`` - ``詳細設定`` - +``環境変数`` - ``システム環境変数`` で) django-admin.py のインストールされ +ている場所を指すように変更してください. + +一般論として,一つの Django プロジェクトだけで作業しているなら, +``manage.py`` を使う方が簡単といえるでしょう. ``django-admin.py`` と +``DJANGO_SETTINGS_MODULE`` や ``--settings`` コマンドラインオプション +を使えば,複数の Django 設定ファイルを切替えて操作できます. + +使い方 +====== + +``django-admin.py action [options]`` + +``manage.py action [options]`` + +``action`` には,このドキュメントで挙げているいずれかのアクション +を指定します. ``options`` は省略可能で,このドキュメントで挙げている +ゼロ個から複数個のオプションを指定します. + +``django-admin.py --help`` を実行すると,利用できる全てのアクションと +オプションの詳細なリストの入ったヘルプメッセージを出力します. + +ほとんどのアクションは ``appname`` のリストを引数にとります. ``appname`` +はモデルの入ったパッケージの名前です.例えば ``INSTALLED_APPS`` に +``mysite.blog`` を追加している場合,このアプリケーションの ``appname`` +は ``blog`` です. + +.. _Available actions: + +利用可能なアクション +==================== + +adminindex [appname appname ...] +---------------------------------------- + +指定した appname に対する admin-index テンプレート断片 (snippet) を出力し +ます. + +admin-index テンプレート断片は, admin のインデクスページのルック&フイー +ルをカスタマイズしたい場合に使って下さい.詳しくは +`チュートリアルその 2`_ を参照してください. + +.. _`チュートリアルその 2`: ../tutorial02/ + +createcachetable [tablename] +---------------------------- + +データベースキャッシュバックエンドで使うための, ``tablename`` という +名前のキャッシュテーブルを生成します.詳しくは +`cache のドキュメント`_ を参照してください. + +.. _`cache のドキュメント`: ../cache/ + +dbshell +------- + +``DATABASE_ENGINE`` 設定に指定されたデータベースエンジンに対し, +``DATABASE_USER`` および ``DATABASE_PASSWORD`` 等の設定に従ってコマンドライ +ンクライアントを起動します. + + * PostgreSQL の場合には ``psql`` を実行します. + * MySQL の場合には ``mysql`` を実行します. + * SQLite の場合には ``sqlite3`` を実行します. + +このコマンドはプログラムが ``PATH`` 上にあると想定しているので,単純に +プログラム名で呼び出したとき (``psql``, ``mysql``, ``sqlite3``) に見つかる +プログラムを使います.プログラムの場所を手動で指定する方法はありません. + +diffsettings +------------ + +現在の設定ファイルと Django のデフォルト設定との差分を表示します. + +デフォルト設定にない設定の末尾には ``"###"`` を追加します.例えば, +デフォルト設定には ``ROOT_URLCONF`` 変数がないので, ``diffsettings`` +の出力中では ``ROOT_URLCONF`` の末尾に ``"###"`` が付きます. + +デフォルト設定の完全なリストを見たければ, +``django/conf/global_settings.py`` にある Django のデフォルト設定を参照して +ください. + +dumpdata [appname appname ...] +------------------------------ + +指定したアプリケーション (複数指定可) に関係した全てのデータをデータベース +から取り出し,標準出力に出力します. + +デフォルトでは,データベースの内容は JSON 形式で出力されます.出力を他の形 +式にしたければ, ``--format`` オプション (例えば ``format=xml``) を使ってく +ださい. ``--format`` には, (``SERIALIZATION_MODULES`` 設定で指定したもの +を含む) Django 対応のシリアライゼーションバックエンドを指定できます. + +アプリケーション名を指定しなかった場合,インストール済みのアプリケーション +全てのデータをダンプします. + +``dumpdata`` の出力は ``loaddata`` の入力に使えます. + +flush +----- + +データベースを syncdb 直後の状態に戻します.全てのデータがデータベースから +除去され,同期直後に呼び出される全てのハンドラが再度実行されます.また, +``initial_data`` フィクスチャも再インストールされます. + +inspectdb [dbname] +------------------ + +``DATABASE_NAME`` 設定で指定されたデータベース上のテーブルに対するイントロ +スペクションを行い,Django モデルモジュール (``models.py``) を標準出力に出 +力します. + +古いデータベースを持っていて,それを Django で使いたい場合に使ってくだ +さい.スクリプトはデータベースを調べ,データベース内の各テーブルに対す +るモデルを生成します. + +想像の通り,生成されるモデルは,テーブルの各フィールド名に対応する属性 +を持ちます.``inspectdb`` はフィールド名の出力に際して以下のようないく +つかの特殊なケースを持っているので注意して下さい: + + * ``inspectdb`` があるカラムの型に対して適切なモデルのフィールド型 + を決定できなかった場合, ``TextField`` が使われ,生成されたモデ + ルの該当するフィールド名の次の行に, + ``'This field type is a guess.'`` というコメントが入ります. + + * データベースのカラム名が Python の予約語 (``'pass'``, ``'class'``, + ``'for'`` など) の場合, ``inspectdb`` は属性名の後ろに ``'_field'`` + を追加します.例えば,テーブルに ``'for'`` という名前のフィールドがあ + れば,生成されるモデルは ``'for_field'`` という名前のフィールドを持ち, + このフィールドの ``db_column`` 属性は ``'for'`` になります. + ``inspectdb`` はフィールド名の次の行に, + ``'Field renamed because it was a Python reserved word.'`` というコメ + ントを追加します. + +この機能は単に手間を省くためのもので,しっかりしたモデル生成を行うため +のものではありません.実行した後に生成されたモデルを自分で確かめてカス +タマイズを行うことになるでしょう.具体的には,他のモデルを参照しているよう +なモデルが正しい順番で並ぶようにします. + +PostgreSQL や MySQL を使っている場合,イントロスペクションで主キーを自動的 +に決定し,必要な場所に ``primary_key=True`` を追加します. + +``inspectdb`` は PostgreSQL, MySQL および SQLite で動作します.外部キー +の検出は PostgreSQL と一部の MySQL テーブル形式でのみ有効です. + +loaddata [fixture fixture ...] +------------------------------ + +名前付きのフィクスチャを探し,その中身をデータベースにロードします. + +*フィクスチャ* (fixture) とは,データベースに入れるデータをシリアライズして +格納したファイル群を指します.各フィクスチャファイルには固有の名前を付けら +れますが,ある名前のフィクスチャを複数のディレクトリに入れても構いませんし, +複数のアプリケーション内に配置してもかまいません. + +Django は以下の 3 種類の場所からフィクスチャを探します: + + 1. インストール済みの各アプリケーションの ``fixtures`` ディレクトリ + 2. ``FIXTURE_DIRS`` 設定に指定したディレクトリ + 3. fixture に直接指定したパス + +Django は上記の場所に見つかった全てのフィクスチャファイルの中から,指定した +フィクスチャ名と一致するファイルをロードします. + +フィクスチャ名にファイル拡張子を指定すると,指定した型のフィクスチャだけが +ロードされます.例えば:: + + django-admin.py loaddata mydata.json + +のようにすると, ``mydata`` という名前の JSON フィクスチャだけがロードされ +ます.フィクスチャの拡張子は, (``json`` や ``xml`` のように) シリアライザ +の登録名に対応していなければなりません. + +拡張子を省略すると, Django は全ての形式にフィクスチャを対象にフィクスチャファイルを検索します.例えば:: + + django-admin.py loaddata mydata + +のようにすると, ``mydata`` という名前の全てのフィクスチャを探します.フィ +クスチャディレクトリに ``mudata.json`` という名前のファイルがあれば, JSON +形式のフィクスチャとしてロードされます.同じ名前で別のフィクスチャ形式のも +のが見つかった場合 (例えば, ``mydata.json`` と ``mydata.xml`` が同じディレ +クトリ下にあった場合),フィクスチャのインストールは中止され,それまでに +``loaddata`` によってロードされたデータは全てデータベースから削除されます. + +フィクスチャの名前にはディレクトリ名を入れても構いません.ディレクトリ部分 +を指定すると,各検索パスに追加されます.例えば:: + + django-admin.py loaddata foo/bar/mydata.json + +とすると,インストール済みの各アプリケーションのディレクトリ ```` +について ``/fixtures/foo/bar/mydata.json`` を, ``FIXTURE_DIRS`` +の各ディレクトリ ```` について ``/foo/bar/mydata.json`` +を,そして相対パス ``foo/bar/mydata.json`` を探します. + +フィクスチャファイルの処理順は決まっていませんが,全てのフィクスチャのイン +ストールは単一のトランザクションで行われるため,あるフィクスチャが別のフィ +クスチャに対する参照を持っていてもかまいません.データベースバックエンドが +行レベルの制約 (row-level constraint) をサポートしているばあい,制約はトラ +ンザクションの最後にチェックされます. + +.. admonition:: MySQL とフィクスチャ + + 残念ながら,MySQL は Django のフィクスチャに関する全ての機能を利用でき + るわけではありません. MyISAM を使っている場合, MySQL はトランザクショ + ンや制約をサポートしていないので,複数のフィクスチャファイルに対するロー + ルバックを行えず,フィクスチャデータの検証も行えません.一方, InnoDB + を使っている場合,データファイル間で前方参照を行えません. MySQL は行制 + 約のチェックをトランザクションコミット直前まで遅延するためのメカニズム + を備えていないからです. + +reset [appname appname ...] +--------------------------- + +指定した appname に対して ``sqlreset`` と同じ操作を実行します. + +runfcgi [options] +----------------- + +FastCGI プロトコルをサポートする Web サーバ向けの一連の FastCGI プロセス群 +を起動します.詳しくは `FastCGI による運用 <../fastcgi/>`_ を参照してくださ +い. Python の FastCGI インタフェースモジュールである `flup`_ が必要です. + +.. _FastCGI deployment documentation: ../fastcgi/ +.. _flup: http://www.saddi.com/software/flup/ + +runserver [optional port number, or ipaddr:port] +------------------------------------------------ + +ローカルマシン上に軽量な開発用ウェブサーバを立ち上げます.デフォルトで +は,サーバは IP アドレス 127.0.0.1,ポート番号 8000 で動作します. +IP アドレスやポート番号は明示的に指定できます. + +このスクリプトを通常ユーザの権限下で実行した場合 (そうするように勧めま +す),ポート番号を低い値にできないかもしれません.値の低いポート番号は +スーパユーザ (root) 用に予約されているからです. + +**開発用サーバをプロダクションサーバとして使ってはなりません.** +開発用サーバはセキュリティ検査もパフォーマンステストも行われていません +(我々が目指しているのは Web フレームワークの開発であり,このサーバを改良し +て運用環境でも利用できるようにするのは Django プロジェクトの目的とするとこ +ろではありません.) + +開発サーバはリクエストを受け付ける度に,必要に応じて自動的に Python コー +ドをリロードします.このため,コードの変更を反映させるためにいちいちサー +バを際起動しなくてもよくなっています. + +サーバの起動時や,サーバの稼働中に Python コードを変更した場合,開発用 +サーバはインストールされている全てのモデルを自動的に検証します (後述の +``validate`` オプションを参照してください).検証時にエラーが見つかった場 +合,エラーは標準出力に出力されますが,サーバは停止しません. + +ポート番号を別々にしているかぎりいくつでもサーバを起動できます. +``django-admin.py runserver`` を複数回起動するだけです. + +デフォルトの IP アドレスである 127.0.0.1 は,ネットワーク上の他のマシ +ンからは利用できません.開発サーバをネットワーク上の他のマシンから +見えるようにするには,サーバホスト固有の IP アドレス (例えば +``192.168.2.1``) または ``0.0.0.0`` を使って下さい. + +例: +~~~ + +IP アドレス 127.0.0.1,ポート番号 7000:: + + django-admin.py runserver 7000 + +IP アドレス 1.2.3.4,ポート番号 7000:: + + django-admin.py runserver 1.2.3.4:7000 + +.. _Serving static files with the development server: + +開発用サーバで静的なファイルを提供する +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +デフォルトでは,開発用サーバはサイト用の静的ファイル (CSSファイル,画像, +``MEDIA_ROOT_URL`` 下のファイルなど) を全く提供しません. Django に静的メディ +アを提供させたければ, `静的なファイルの提供方法`_ を参照してくださ +い. + +.. _`静的なファイルの提供方法`: ../static_files/ +.. _serving static files: ../static_files/ + +.. _Turning off auto-reload: + +自動リロードを切る +~~~~~~~~~~~~~~~~~~ + +開発サーバに実行中にコードを自動リロードさせたくなければ,以下のように +``--noreload`` オプションを使ってください:: + + django-admin.py runserver --noreload + + +shell +----- + +Python の対話インタプリタを起動します. + +IPython_ がインストールされている場合,Django は IPython を使おうとします. +IPython がインストールされていて,かつ「普通の」インタプリタを使いたいのな +ら,以下のように ``--plain`` オプションを使って下さい:: + + django-admin.py shell --plain + +.. _IPython: http://ipython.scipy.org/ + +sql [appname appname ...] +------------------------- + +指定した appname の CREATE TABLE SQL 文を出力します. + +sqlall [appname appname ...] +---------------------------- + +指定した appname の CREATE TABLE および初期データ入力のための +SQL 文を出力します. + +初期データの指定方法は ``sqlinitialdata`` の説明を参照してください. + +sqlclear [appname appname ...] +-------------------------------------- + +指定した appname の DROP TABLE SQL 文を出力します. + +sqlindexes [appname appname ...] +---------------------------------------- + +指定した appname の CREATE INDEX SQL 文を出力します. + +sqlcustom [appname appname ...] +-------------------------------------------- + +指定した appname のカスタム SQL 文を出力します. + +このコマンドは,指定した各アプリケーションのモデルについて, ```` +をアプリケーションの名前, ```` をモデルの名前を全て小文字にした +文字列として, ``/sql/.sql`` という名前のファイルを探し +ます.例えば, ``news`` というアプリケーションで ``Story`` というモデルが定 +義されていれば, ``sqlinitialdata`` は ``news/sql/story.sql`` というファイ +ルを探して読みだし,その内容をこのコマンドの出力の末尾に追加します. + +各 SQL ファイルには,有効な SQL を入れることになっています. SQL ファイルの +内容は,モデルのテーブル生成文を全て実行した後に,データベースに直接パイプ +されます.テーブルに対して変更を加えたり, SQL 関数をデータベースに組み込む +には,この SQL フックを使ってください. + +sqlindexes [appname appname ...] +---------------------------------------- + +指定したアプリケーションに対する CREATE INDEX SQL 文を出力します. + +sqlreset [appname appname ...] +-------------------------------------- + +指定した appname に対する DROP TABLE SQL 文を出力し, +その後で CREATE TABLE SQL 文を出力します. + +sqlsequencereset [appname appname ...] +---------------------------------------------- + +指定した appname の PostgreSQL シークエンスをリセットするための +SQL 文を出力します. + +詳しくは http://simon.incutio.com/archive/2004/04/21/postgres を参照し +てください. + +startapp [appname] +------------------ + +現在のディレクトリに, appname に指定した名前の Django アプリケーショ +ンディレクトリ階層を作成します. + +startproject [projectname] +-------------------------- + +現在のディレクトリに, projectname に指定した名前の Django プロジェク +トディレクトリ階層を作成します. + +syncdb +------ + +``INSTALLED_APPS`` に登録されており,まだテーブルを作成していないアプリケー +ション全てのテーブルを作成します. + +このコマンドは,新たなアプリケーションをプロジェクトに追加し,データベース +にインストールしたい場合に使って下さい.アプリケーションには, Django に付 +属しているアプリケーションで,デフォルトで ``INSTALLED_APPS`` に入っている +ものも含みます.新たなプロジェクトを開始する際には,このコマンドを実行して +デフォルトのアプリケーションをインストールする必要があります. + +``django.contrib.auth`` アプリケーションをインストールした場合には, +``syncdb`` はスーパユーザを作成するか尋ねます. + +``syncdb`` はまた, ``initial_data`` という名前のフィクスチャを探してインス +トールします.フィクスチャデータファイルの詳細は ``loaddata`` のドキュメン +トを参照してください. + +test +---- + +インストールされている全てのモデルからテストを捜し出して実行します. +詳しくは `Django アプリケーションのテスト `_ を参照してくださ +い. + + +validate +-------- + +インストールされている (``INSTALLED_APPS`` に登録されている) 全てのモ +デルを検証 (validate) し,エラーがあれば標準出力に出力します. + +利用可能なオプション +==================== + +--settings +---------- + +使用例:: + + django-admin.py init --settings=mysite.settings + +管理対象のプロジェクトの設定モジュールを明示的に指定します.設定モジュー +ルは Python のパッケージ表現構文,すなわち "mysite.settings" のような形式で +指定します.このオプションを指定しない場合,``django-admin.py`` は環境変数 +``DJANGO_SETTINGS_MODULE`` を使います. + +``manage.py`` は ``DJANGO_SETTINGS_MODULE`` をきちんと設定してくれるの +で,このオプションは必要ありません. + +--pythonpath +------------ + +使用例:: + + django-admin.py syncdb --pythonpath='/home/djangoprojects/myproject' + +指定したファイルシステムパスを Python の `import 検索パス`_ に追加 +します.このオプションを指定しない場合, ``django-admin.py`` は環境変 +数 ``PYTHONPATH`` を使います. + +``manage.py`` は Python パスをきちんと設定してくれるので,このオプション +は必要ありません. + +.. _`import 検索パス`: http://diveintopython.org/getting_to_know_python/everything_is_an_object.html + +--plain +------- + +IPython をインストールしている場合,対話シェルの起動に IPython ではなく通常 +の Python 対話シェルを使います. + +--format +-------- + +使用例:: + + django-admin.py dumpdata --format=xml + +ダンプ出力に使う形式を指定します.出力形式の名前はシリアライザの登録名でな +ければなりません. + + +--help +------ + +利用できる全てのアクションとオプションの詳細なリストの入ったヘルプメッ +セージを出力します. + +--indent +-------- + +使用例:: + + django-admin.py dumpdata --indent=4 + +出力を整形するためのインデント幅をスペースの個数で指定します.デフォルトで +は,出力は整形 *されません* .出力の整形が行われるのは,このオプションを指 +定したときだけです. + +--noinput +--------- + +django-admin の実行中に,ユーザに入力を促さないようにさせます. +django-admin スクリプトを自動的に実行したい場合に便利です. + +--noreload +---------- + +開発サーバ実行中の自動リロード機能を無効にします. + +--version +--------- + +現在の Django のバージョンを表示します. + +表示例:: + + 0.9.1 + 0.9.1 (SVN) + +--verbosity +----------- + +使用例:: + + django-admin.py syncdb --verbosity=2 + +コンソールに出力する通知情報やデバッグ情報の量を制御します. '0' は出力なし, +'1' は通常の出力, '2' は多めの出力です. + +--adminmedia +------------ + +使用例:: + + django-admin.py manage.py --adminmedia=/tmp/new-admin-style/ + +開発サーバを起動する際に, admin インタフェース用の CSS や JavaScript ファ +イルを探す場所を Django に教えます.通常,これらのファイルは Django のソー +スツリーから取り出して使うようになっていますが,このオプションを使えば,自 +作のサイト用に変更を加えているデザイナがカスタムバージョンのスタイルシート +や JavaScript をテストできるようになります. + +.. _Extra niceties: + +その他のからくり +================ + +シンタクスの色づけ +------------------ + +SQL 文を標準出力に出力する ``django-admin.py`` / ``manage.py`` コマンドは, +端末が ANSI カラー出力をサポートする場合にはコードを色づけして表示します. +ただし,出力を別のプログラムにパイプしている場合には色づけを行いません. + +bash での補完 +------------- + +bash シェルを使っているのなら, Django の bash 補完スクリプトのインストール +を検討してみてください.スクリプトは Django 配布物の +``extras/django_bash_completion`` にあります. bash 補完機能を使うと, +``django-admin.py`` および ``manage.py`` コマンドをタブ補完できるようになり +ます.例えば: + + * ``django-admin.py`` とタイプします. + * [TAB] を押すと,利用可能な全てのオプションを表示します. + * ``sql`` とタイプして [TAB] を押すと, ``sql`` で始まる全てのオプショ + ンを表示します. + diff --git a/documentation.txt b/documentation.txt new file mode 100644 index 0000000..0b7e59d --- /dev/null +++ b/documentation.txt @@ -0,0 +1,159 @@ +=========================== +Django ドキュメントの読み方 +=========================== + +:revision-up-to: 4805 (release 0.96) + +私達は, Django のドキュメントが,有用で読みやすくできるだけ詳細であるよう +多大な努力を投じています.ここでは,ドキュメントを活用するコツと,ドキュメ +ントを書くときのスタイルガイドラインを示します. + +(そう,これはドキュメントのドキュメントです.ドキュメントの読み方の読み方に +ついてドキュメント化するつもりはありませんから,安心してください.) + +.. _How documentation is updated: + +ドキュメント更新の方針 +====================== + +Django のコードベースが毎日のように開発と改良を重ねているように,ドキュメン +トも常に改良を重ねています.ドキュメントの改良は以下のような理由に基づいて +行われます: + + * 文法やタイプミスなどの誤りを修正する場合. + * 既存の内容に対して,新たに情報や例題を追加する場合. + * まだ解説されていない Django の機能をドキュメント化する場合 (未ドキュ + メントの機能は減りつつありますが,まだいくつか残っています). + * 新たな機能が追加され,ドキュメントも追加する場合.あるいは, Django + の API や挙動が変更された場合. + +Django のドキュメントはコードと同じソースコード管理システム下にあり, +Subversion リポジトリの `django/trunk/docs`_ ディレクトリ以下に置かれていま +す.各ドキュメントは,例えば「汎用ビュー」フレームワークや,データベースモ +デルの構築方法といった具合に,個別のトピックごとに別々のテキストファイルに +なっています. + +.. _django/trunk/docs: http://code.djangoproject.com/browser/django/trunk/docs + +.. _Where to get it: + +ドキュメントの入手 +================== + +Django のドキュメントを入手するにはいくつか方法があります.おすすめの順に以 +下に示します: + +Web から +-------- + +Django ドキュメントの最新版は ../ +にあります.ここにある HTML ページは,ソースコード管理システム上のテキスト +ファイルから 15 分毎に自動生成されているものです.従って,これらのファイル +は「最新最良の」 Django に対応しています.つまり,最近の修正や追加事項を反 +映していて,まだ開発版でしか使えないような最新の機能についても部分的に解説 +しているわけです (下記の `バージョン間の相違点`_ を参照してください). + +Web ベースのドキュメントの素晴らしい点は,ドキュメントの末尾にあるコメント +セクションです.ここには現在のドキュメントに対する変更や修正,提案などを書 +き込めます.Django の開発者達はコメントを頻繁にモニタしていて,ドキュメント +の改良に役立てています. + +ドキュメント改良のお手伝いは大歓迎です.方法は簡単です.ただし,コメントを +投稿するときは,一般的なテクニカルサポートに関わる質問ではなく,ドキュメン +ト自体に関する内容にしてください. Django の構成に関する個別の問題はドキュ +メントのコメント欄にではなく, `django-users メーリングリスト`_ にお願いし +ます. + +.. _django-users mailing list: http://groups.google.com/group/django-users +.. _`django-users メーリングリスト`: http://groups.google.com/group/django-users + +.. _In plain text: + +プレーンテキスト +---------------- + +オフラインでテキストを読む方が便利なら,プレーンテキスト形式で Django ドキュ +メントを読めます. + +Django の公式リリース版を使っているなら,ソースコードのアーカイブパッケージ +(tarball) に ``docs/`` ディレクトリが入っています.このディレクトリには各リ +リースの全てのドキュメントが入っています. + +Django の開発版 (いわゆる Subversion "trunk") を使っている場合, ``docs/`` +ディレクトリに全てのドキュメントが入っています.最新版を取得したければ, +Python コードの更新と同様, ``svn update`` を実行してください. + +最新の Django ドキュメントを Subversion から取り出すには,以下のようなシェ +ルコマンドを使います:: + + svn co http://code.djangoproject.com/svn/django/trunk/docs/ django_docs + +テキストドキュメントの便利でローテクな使い方の一つに Unix の ``grep`` ユー +ティリティを使った全ドキュメント検索があります.例えば,以下のようにすれば, +"edit_inline" について触ている部分を表示できます:: + + grep edit_inline /path/to/django/docs/*.txt + +.. _Formatting: + +フォーマット変換 +~~~~~~~~~~~~~~~~ + +テキストドキュメントは ReST (ReStructuredText) 形式で書かれています. ReST +はただ単体でも読みやすいだけでなく, HTML のような他のフォーマットにも簡単 +に変換できるようになっています. HTML に変換したければ, ReST のテキストド +キュメントを djangoproject.com の HTML 形式に変換するスクリプトが, Django +の Subversion リポジトリの +`djangoproject.com/django_website/apps/docs/parts/build_documentation.py`_ +にあります. + +.. _djangoproject.com/django_website/apps/docs/parts/build_documentation.py: http://code.djangoproject.com/browser/djangoproject.com/django_website/apps/docs/parts/build_documentation.py + +.. _Differences between versions: + +バージョン間の相違点 +==================== + +前述したように, Subversion リポジトリに入っているテキストドキュメントは +変更や追加によって「最新最良」の状態にあります.変更によって,開発版,すな +わち Subverion ("trunk") 版の Django に新たに登場した機能がテキストに記載さ +れることがよくあります.このため, Django の各バージョン間で一貫したドキュ +メンテーションポリシをここで示しておきます. + +我々は,以下のポリシに従っています: + + * djangoproject.com の第一のドキュメントは Subversion から生成される + HTML 形式のドキュメントです.これらのドキュメントは常に最新の Django + 公式リリースと,最新のリリース *以後* に追加/変更された機能に対応し + ています. + + * Django の開発版に機能を追加する場合,可能ならば同じ Subversion のコミッ + トトランザクションにおいてドキュメントの変更もチェックインします. + + * 追加/変更された機能を区別するため, + (**開発版の Django で新たに追加された機能です (New in Django + development version)** という文を使います.このため, + djangoproject.com で公開されている最新のドキュメントは,最新のリリー + ス *および* 開発版のユーザの両方から利用できます. + + * 特定のリリース版のドキュメントは,公式リリース時に一度フリーズされま + す.従って,ドキュメントはその時のスナップショットになります.以前の + バージョンに遡ってセキュリティアップデートその他の変更を行った場合に + のみ,例外的にドキュメントを更新します.ドキュメントのフリーズ後は, + 各ドキュメントの冒頭に "These docs are frozen for Django version XXX" + という一文と,ドキュメントの最新版へのリンクを追加します. + + * リリースに備えてドキュメントがフリーズされた時点で,最新版のドキュメ + ントに対するコメントを除くコメントは削除されます.これはメンテナンス + とユーザビリティのために,ユーザがドキュメントに対するコメントを書け + る場所をただひとつにしておくためです.もちろん,以前のバージョンを使っ + ていてつまづいているユーザがいることは知っていますが,複数バージョン + のドキュメントにコメントを許したても,その利益がユーザビリティ上の問 + 題を補うことは決してないだろうというのが私達の考えです. + + * `Web のドキュメントメインページ`_ には,以前の全てのバージョンのドキュ + メントに対するリンクがあります. + +.. _main documentation Web page: ../ +.. _`Web のドキュメントメインページ`: ../ + diff --git a/email.txt b/email.txt new file mode 100644 index 0000000..c8290d0 --- /dev/null +++ b/email.txt @@ -0,0 +1,208 @@ +============== +e-mail の送信 +============== + +:revision-up-to: 4805 (release 0.96) + +Python の `smtplib ライブラリ`_ を使えば,比較的簡単に電子メールを送信でき +ますが, Django ではこのライブラリへの軽量ラッパを二つ用意して,電子メール +の送信を極めて素早くおこなえるようにしています. + +コードは: ``django.core.mail`` にあります. + +.. _`smtplib ライブラリ`: http://www.python.jp/doc/release/lib/module-smtplib.html +.. _smtplib library: http://www.python.org/doc/current/lib/module-smtplib.html + + +.. _Quick example: + +お手軽な例 +========== + +二行だけです:: + + from django.core.mail import send_mail + + send_mail('Subject here', 'Here is the message.', 'from@example.com', + ['to@example.com'], fail_silently=False) + +.. note:: + + ``django.core.mail`` で送信される電子メールの文字セットは + `DEFAULT_CHARSET 設定`_ の値に設定されます. + +.. _`DEFAULT_CHARSET 設定`: ../settings/#default-charset +.. _DEFAULT_CHARSET setting: ../settings/#DEFAULT_CHARSET + + + +send_mail() +=========== + +電子メールを送信する最も簡単な方法は ``django.core.mail.send_mail()`` +関数です.この関数の定義は以下のようになっています:: + + send_mail(subject, message, from_email, recipient_list, + fail_silently=False, auth_user=None, + auth_password=None) + +``subject``, ``message``, ``from_email`` および ``recipient_list`` は必須の +パラメタです. + + * ``subject``: 文字列です. + * ``message``: 文字列です. + * ``from_email``: 文字列です. + * ``recipient_list``: 文字列からなるリストで,各々が電子メールアドレス + を表します. ``recipient_list`` に入っているユーザは,お互いに他のユー + ザをメールの "To:" フィールドで見られます. + * ``fail_silently``: ブール型の値です. ``False`` なら ``send_mail`` は + ``smtplib.SMTPException`` 例外を出すようになります. + 送出されうる例外のリストは `smtplib のドキュメント`_ を参照してくださ + い.いずれの例外も ``SMTPException`` のサブクラスです. + * ``auth_user``: オプションです. SMTP サーバでの認証に使うユーザ名です. + この値を指定しなければ, Django は ``EMAIL_HOST_USER`` 設定を使います. + * ``auth_password``: オプションです. SMTP サーバでの認証に使うパスワー + ドです.この値を指定しなければ, Django は ``EMAIL_HOST_PASSWORD`` 設 + 定を使います. + +.. _`smtplib のドキュメント`: + http://www.python.jp/doc/release/lib/module-smtplib.html +.. _smtplib docs: + http://www.python.org/doc/current/lib/module-smtplib.html + + +send_mass_mail() +================ + +``django.core.mail.send_mass_mail()`` は一括電子メール (mass e-mail) の送信 +用の関数です.この関数の定義は以下のようになっています:: + + send_mass_mail(datatuple, fail_silently=False, + auth_user=None, auth_password=None): + +``datatuple`` はタプルで,各要素は以下の形式になっています:: + + (subject, message, from_email, recipient_list) + +``fail_silently``, ``auth_user`` および ``auth_password`` は +``send_mail()`` と同じです. + +``datatuple`` の各要素ごとに個別の電子メールメッセージを作成して送信します. +``send_mail()`` と同様,同じ ``recipient_list`` に入っている受信者は,他の +受信者を "To:" フィールドで見られます. + +.. _`send_mass_mail() vs. send_mail()`: + +send_mass_mail() と send_mail() +------------------------------- + +``send_mass_mail()`` と ``send_mail()`` の大きな違いは, ``send_mail()`` +は実行の度にメールサーバに接続するのに対し, ``send_mass_mail()`` は全ての +メッセージの送信に一つの接続を使う点です.このため, ``send_mass_mail()`` +の方が少しだけ効率的です. + +.. _`mail_admins()`: + +mail_admins() +============= + +``django.core.mail.mail_admins()`` は `ADMINS 設定`_ に書かれたサイト管理者へ +の電子メール送信を行うためのショートカットです.関数の定義は以下の通りです:: + + mail_admins(subject, message, fail_silently=False) + +``mail_admins()`` はサブジェクトの先頭に `EMAIL_SUBJECT_PREFIX 設定`_ の値 +を付加します.デフォルトは ``"[Django] "`` です. + +電子メールの "From:" ヘッダは `SERVER_EMAIL 設定`_ の設定値になります. + +このメソッドは利便性と可読性のために用意されています. + +.. _ADMINS 設定: ../settings/#admins +.. _EMAIL_SUBJECT_PREFIX 設定: ../settings/#email-subject-prefix +.. _SERVER_EMAIL 設定: ../settings/#server-email +.. _ADMINS setting: + ../settings/#admins +.. _EMAIL_SUBJECT_PREFIX setting: + ../settings/#email-subject-prefix +.. _SERVER_EMAIL setting: + ../settings/#server-email + + +mail_managers() +=============== + +``django.core.mail.mail_managers()`` は ``mail_admins`` と同じですが, +電子メールを `MANAGERS 設定`_ に書かれたサイトマネジャに送信します +関数は以下のように定義されています:: + + mail_managers(subject, message, fail_silently=False) + +.. _`MANAGERS 設定`: ../settings/#managers +.. _MANAGERS setting: + ../settings/#managers + +.. _Examples: + +例 +== + +以下の例は,単一の電子メールを john@example.com と jane@example.com に送信 +します.両方の宛先が "To:" に表示されます:: + + send_mail('Subject', 'Message.', 'from@example.com', + ['john@example.com', 'jane@example.com']) + +以下の例は,単一の電子メールを john@example.com と jane@example.com に送信 +しますが,受け取り人はそれぞれ別々のメッセージを受け取ります:: + + datatuple = ( + ('Subject', 'Message.', 'from@example.com', ['john@example.com']), + ('Subject', 'Message.', 'from@example.com', ['jane@example.com']), + ) + send_mass_mail(datatuple) + + +.. _Preventing header injection: + +ヘッダインジェクションの抑制 +============================ + +`ヘッダインジェクション`_ とは,スクリプトが生成したメッセージの "To:" や +"From:" に,攻撃者が余分な電子メールヘッダを挿入するというセキュリティ侵害 +です. + +上記で解説した Django の電子メール機能では,ヘッダの値に改行を使えないよう +にしてヘッダインジェクションを防御しています. ``subject``, ``from_email`` +および ``recipient_list`` が (Unix, Windows または Mac 形式の) 改行を含む場 +合,電子メール送信関数 (``send_mail()`` など) は +``django.core.mail.BadHeaderError`` 例外 (``ValueError`` のサブクラス) を送 +出します.このため,電子メールは送信されません.電子メール送信関数に渡すデー +タの検証はユーザに任されています. + +``message`` の文字列の先頭にヘッダが入っている場合,ヘッダは単に電子メッセー +ジ本文の先頭部分として出力されます. + +以下に示すのは, ``subject``, ``message`` および ``from_email`` をリクエス +トの POST データから受け取り,メールを admin@example.com に送信し,終了した +ら "/contact/thanks/" にリダイレクトする例です:: + + from django.core.mail import send_mail, BadHeaderError + + def send_email(request): + subject = request.POST.get('subject', '') + message = request.POST.get('message', '') + from_email = request.POST.get('from_email', '') + if subject and message and from_email: + try: + send_mail(subject, message, from_email, ['admin@example.com']) + except BadHeaderError: + return HttpResponse('Invalid header found.') + return HttpResponseRedirect('/contact/thanks/') + else: + # 実際にはマニピュレータを使って適切な検証エラーを + # 取得するべきでしょう. + return HttpResponse('Make sure all fields are entered and valid.') + +.. _`ヘッダインジェクション`: http://securephp.damonkohler.com/index.php/Email_Injection +.. _Header injection: http://securephp.damonkohler.com/index.php/Email_Injection diff --git a/faq.txt b/faq.txt new file mode 100644 index 0000000..e7bd474 --- /dev/null +++ b/faq.txt @@ -0,0 +1,827 @@ +=========================== +Django についてよくある質問 +=========================== + +:revision-up-to: 4805 (release 0.96) + +.. contents:: + +.. _General questions: + +一般的な質問 +============ + +.. _Why does this project exist?: + +なぜこんなプロジェクトがあるのですか? +-------------------------------------- + +Django は極めて実践的な要請のもとで成長してきました.Web 新聞を発行している +WorldOnline では,効果的な Web アプリケーションを,ジャーナリズムとして成立 +する締め切りに間に合うように構築せねばなりません.変転の激しいニュースルー +ムにおいて, WorldOnline は複雑な Web アプリケーションをコンセプトから立ち +上げ公開にもっていくまでの時間を唯一の課題としているのです. + +同時に, WorldOnline の Web 開発者たちは,こと Web 開発の王道に関しては一貫 +して完璧主義者です. + +こうした理由から Django は Web アプリケーションをただ素早く作れるだけではな +く,Web 開発の *王道* に従って作成できるように設計されているのです. +2003 年,WorldOnline の開発者 (Adrian Holovaty と Simon Willison) は PHP に +見切りをつけ, Python による Web 開発に取り組みはじめました.集約的で高い双 +方向性を備えた Lawrence.com のようなサイト開発の中で,彼らは Web アプリケー +ションをより迅速に開発できるように,サイトのコードから汎用の Web 開発フレー +ムワークを切り出し, 2 年近くの間ずっと改良を加えながら使い込んできました. + +2005 年の夏, World Online はこれまでの開発の成果を Django としてオープンソー +ス化する決定を下しました. Django は `Apache`_, `Python`_, そして +`PostgreSQL`_ をはじめとする様々なオープンソースプロジェクトなしでは実現し +ませんでした.そして今,私達はオープンソースコミュニティに多少なりともお返 +しできることにワクワクしているのです. + +.. _Apache: http://httpd.apache.org/ +.. _Python: http://www.python.org/ +.. _PostgreSQL: http://www.postgresql.org/ + +.. _What does "Django" mean, and how do you pronounce it?: + +"Django" とはどういう意味で,どのように発音するのですか? +--------------------------------------------------------- + +Django は 1930 年代から 1950 年代初期にかけて活躍したジプシージャズのギタリ +スト, `ジャンゴ・ラインハルト`_ (`Django Reinhardt`_) にちなんで名付けられ +ました.今日では,ジャンゴは歴史上最も優れたギタリストの一人に数えられてい +ます. + +彼の曲を聞いてみてください.きっと気に入ることでしょう. + +Django は **JANG**-oh ('a' は伸ばす) と発音します.韻は FANG-oh と +同じです. "D" は発音しません。 + +.. _`ジャンゴ・ラインハルト`: http://ja.wikipedia.org/wiki/%E3%82%B8%E3%83%A3%E3%83%B3%E3%82%B4%E3%83%BB%E3%83%A9%E3%82%A4%E3%83%B3%E3%83%8F%E3%83%AB%E3%83%88 +.. _Django Reinhardt: http://en.wikipedia.org/wiki/Django_Reinhardt + + +.. _Is Django stable?: + +Django は安定していますか? +--------------------------- + +はい. World Online は私達は 3 年以上にわたって Django を使ってきました. +Django で構築したサイトは,これまでに 100 万ヒット/時を超えるトラフィック +スパイクに見舞われたことがあり,何度もスラッシュドット効果を喰らっています. +そうですね.きわめて安定です. + +.. _Does Django scale?: + +Django はスケールしますか? +--------------------------- + +はい.ハードウェアというものは,開発時間に比べて安いものですし,それゆえ +Django はユーザが投入可能なハードウェアをできるだけ活用するべく設計されてい +ます. + +Django は「レイヤ間で何も共有しない (shared-nothing)」アーキテクチャなので, +データベースサーバ,キャッシュサーバ, Web/アプリケーションサーバのどのレベ +ルにハードウェアを追加してもかまいません. + +Django はアプリケーションレイヤからのデータベースレイヤを分離し,シン +プルながら強力な `キャッシュフレームワーク`_ を備えています. + +.. _`キャッシュフレームワーク`: ../cache/ +.. _`cache framework`: ../cache/ + +.. _Who's behind this?: + +Django の舞台裏には誰がいるのですか? +------------------------------------- + +Django は米国カンザス州ローレンス (Lawrence, Kansas, USA) のとある新聞の +Web 部門である `World Online`_ で開発されました. + +`Adrian Holovaty`_ + Adrian はジャーナリズムのバックグラウンドを持った Web 開発者です.彼は + 2 年半の間 World Online のリードプログラマを勤め,その間に Django を開 + 発して World Online サイトを実装しました.現在彼は washingtonpost.com + で働いており,データベースをバックエンドにしたリッチな情報サイトの構築 + に携わるかたわら, Django の開発も継続して監督しています. Adrian は + (Django Reinhardt スタイルの) ギター演奏や, `chicagocrime.org`_ のよう + なサイドプロジェクトのハッキング中が好きです.シカゴ在住です. + + IRC では, ``adrian_h`` と名乗っています. + +`Jacob Kaplan-Moss`_ + Jacob はカリフォルニアから来た男で,コーディングと料理に同じだけ時間を + 割くという生意気野郎です.彼は World Online の開発を指揮しており, + 同時に様々な優れたサイドプロジェクトを積極的にハックしています.彼は + Python-ObjC バインディングに貢献したことがあり, Python で Tivo アプリ + ケーションを書く方法を見つけた最初の男でもあります.最近彼は PSP で動く + Python にどっぷりはまっています.カンザス州ローレンス在住です. + + IRC では ``jacobkm`` と名乗っています. + +`Simon Willison`_ + Simon はイングランドから来た尊敬すべき Web 開発者です.彼は World + Online で 1 年間のインターンシップを過ごし,その間に Adrian とともに + Djang をスクラッチから開発しました.彼はまれに見る情熱家の英国人で, + Web 開発の王道について確固たる信念を持っており,多くの読者をもつ Web 開 + 発に関する blog, http://simon.incutio.com を何年もの間運営してきました. + Simon は現在 Yahoo UK で働いており,「Hacker Liason」の称号を得ています. + イングランド在住です. + + IRC では ``SimonW`` と名乗っています. + +`Wilson Miner`_ + Wilson のデザイン術は,私達をロックスターに仕立てあげてしまいます.日中 + は `Apple`_ のインタラクティブデザイナを勤めています.でも Apple で何を + やっているか聞いてはいけません.そんなことをしたら,彼にシメられちゃい + ますよ.サンフランシスコ在住です. + + IRC では ``wilsonian`` と名乗っています. + +.. _`Apple`: http://www.apple.com/ +.. _`World Online`: http://code.djangoproject.com/wiki/WorldOnline +.. _`Adrian Holovaty`: http://www.holovaty.com/ +.. _`washingtonpost.com`: http://www.washingtonpost.com/ +.. _`chicagocrime.org`: http://www.chicagocrime.org/ +.. _`Simon Willison`: http://simon.incutio.com/ +.. _`simon.incutio.com`: http://simon.incutio.com/ +.. _`Jacob Kaplan-Moss`: http://www.jacobian.org/ +.. _`Wilson Miner`: http://www.wilsonminer.com/ + +.. _Which sites use Django?: + +どんなサイトが Django を使っているのですか? +-------------------------------------------- + +Django wiki には `Django で作られたサイト一覧`_ という特集ページがあり, +日々内容が増えています.自分の Django サイトもどうぞ自由に追加してください. + +.. _`Django で作られたサイト一覧`: http://code.djangoproject.com/wiki/DjangoPoweredSites +.. _list of Django-powered sites: http://code.djangoproject.com/wiki/DjangoPoweredSites + + +.. _Django appears to be a MVC framework, but you call the Controller the "view", and the View the "template". How come you don't use the standard names?: + +Django は MVC フレームワークのようですが,コントローラ (Controller) を「ビュー (view)」と呼び,ビュー (View) を「テンプレート (template)」と呼んでいます.どうして標準的な呼び方をしないのですか? +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +そうですね,呼び名には議論の余地があるでしょう. + +我々の MVC の解釈では,「ビュー」とはユーザに提示されるデータのことをいいま +す.つまり,データが *どのように見えるか* ということではなく,むしろ *どの +データを提示するか* です.ビューは *どのデータを見せるか* であり, +*どう見せるか* ではありません.この二つは明らかに違います. + +というわけで,我々のケースでは,「ビュー」は特定の URL に対する Python コー +ルバック関数になります.なぜなら,コールバック関数はどのデータを提示するか +を決めているからです. + +さらに,テンプレートによってコンテンツとプレゼンテーションの分離がはっきり +しています.Django では,ビューはどのデータを提示するかを決めていますが, +ビューは通常, *どのように* データを提示するかをテンプレートに委ねます. + +では,「コントローラ」はどこに入るのでしょうか. Django の場合,おそらくフ +レームワーク,すなわち URL 設定にしたがってリクエストを適切なビューに送信す +る機構自体がコントローラにあたるといえるでしょう. + +略語がお好みなら, Django を "MTV" フレームワークと呼んでもよいでしょう.つ +まり,モデル (Model),テンプレート (Template),そしてビュー (View) です. +こっちの方がよりしっくりきます. + +最後に,結局重要なのは問題を解決することです.そして,呼び方は何であれ, +Django はわれわれにとって最も理にかなった方法で問題を解決しているのです. + +.. _ does -- why doesn't Django?: + +<フレームワーク X> には <機能 Y> があります -- どうして Django にないのですか? +------------------------------------------------------------------------------- + +世の中には他にも素晴らしい Web フレームワークがあるのは良く知っていますし, +必要であればそこからアイデアを借りるのにやぶさかではありません.とはいえ, +Django はまさに私達が旧態然の Web フレームワークに不満だったからこそ開発さ +れたのであって,「 ができるから」という理由は Django に機能を +追加する十分な理由にはならないということに注意して下さい. + +.. _Why did you write all of Django from scratch, instead of using other Python libraries?: + +なぜ既存の Python ライブラリを使わずスクラッチで Django を作ったのですか? +-------------------------------------------------------------------------- + +Django を書き始めた約 2 年前, Adrian と Simon は少し時間を取って当時利用で +きた様々な Python ウェブフレームワークを試してみました. + +その結果,十分な出来具合のものは一つもないという結論に達したのです. + +私達は好みにうるさいのです.(締め切りを守る) 完璧主義者と呼んでもいいでしょ +う. + +これまでずっと,私達は自分たちがすでに実装済みの機能を実現するオープンソー +スライブラリに出会ってきました.そうしたライブラリに,他の人達が同じ問題を +同じ方法で解決しようとしているのを見ては元気づけられる思いでしたが,自分た +ちのコードの外側に組み込むにはもう遅すぎました.私達はすでにいくつもの運用 +環境で独自のフレームワークを書き上げ,テストし,実装してきており,できたコー +ドは快適なまでに要求を満たしていたのです. + +一方,ほとんどの場合,既存のフレームワークやツールは明らかにある主の根本的, +致命的な欠陥があり,私達を神経質にさせました.結局,私達の哲学に 100% 合う +ものはなかったのです. + +繰り返していいますが,私達は好みにうるさいのです. + +私達の設計哲学は `設計哲学のページ`_ に詳しく書いてあります. + +.. _`設計哲学のページ`: ../design_philosophies/ +.. _design philosophies page: ../design_philosophies/ + +.. _Do you have any of those nifty "screencast" things?: + +かっこいい「スクリーンキャスト」か何かがありますか? +---------------------------------------------------- + +現在進行中だということだけは断言できます.がしかし,私達はまだ Django を改 +良している真最中なので,現状ではなく, Django 1.0 になったときの最終的な状態 +を反映させたいと思っています.言い方を変えれば, Django API はまだ変化する +かもしれないので,それまではスクリーンキャストにまださほどエネルギーを使い +たくないということです. + +とはいいながら, `非公式の Django スクリーンキャスト`_ はあるのでチェックし +てみてください. + +.. _`非公式の Django スクリーンキャスト`: http://www.throwingbeans.org/django_screencasts.html +.. _unofficial Django screencast: http://www.throwingbeans.org/django_screencasts.html + + +.. _Is Django a content-management-system (CMS)?: + +Django はコンテンツ管理システム (CMS) なのでしょうか? +----------------------------------------------------- + +いいえ。 Django は CMS ではありませんし、いわゆる「ターンキーシステム」のよ +うなものでもありません。 Django は Web フレームワークであり、 Web サイトを +構築する際に使えるプログラミングツールにすぎません。 + +例えば、 Django を Drupal_ のようなシステムと比較するのは無意味です。という +のも、 Django はまさに Drupal のようなシステムを *作る* ためのものだからで +す。 + +もちろん、 Django の自動 admin サイトはすばらしく、開発時間の節約になります。 +しかし、 admin サイトは Django というフレームワークのいちモジュールに過ぎま +せん。もっと言うなら、 Django が「 CMS 的な」アプリケーションを作成する上で +とりわけ便利な点を持ってはいますが、そのことが「 CMS 的でない」アプリケーショ +ンの開発に向いていない、なんてことにつながったりはしないのです。 + +.. _Drupal: http://drupal.org/ + +.. _When will you release Django 1.0?: + +いつになったら Django 1.0 をリリースするのですか? +-------------------------------------------------- + +短い答え: Django の API 構成に問題がなくなり, "1.0" に必要と考えている全て +の機能を追加し,以前のバージョンとの互換性を維持できるようになった時点,です. + +Django の `magic-removal ブランチ`_ のマージにより,Django 1.0 への道のりは +大分進みました. + +1.0 になっていないからといってがっかりしないで下さいね. + +.. _magic-removal ブランチ: http://code.djangoproject.com/wiki/RemovingTheMagic +.. _quite a few production sites: http://code.djangoproject.com/wiki/DjangoPoweredSites + +.. How can I download the Django documentation to read it offline?: + +どうやれば Django のドキュメントをダウンロードしてオフラインで読めますか? +-------------------------------------------------------------------------- + +Django のドキュメントは Django tarball リリースの ``docs`` ディレクトリに +あります.これらのドキュメントは ReST (ReStructuredText) 形式で書かれており, +各テキストファイルが Django 公式サイトのページに対応しています. + +ドキュメントは `バージョン管理システム下にある`_ ので,コードの変更状況を閲 +覧するのと同じようにしてドキュメントの変更状況を閲覧できます. + +技術的には, Django サイトのドキュメントは最新の開発版の ReST ドキュメント +から生成されます,従って, Django サイトにあるドキュメントの方が,最新の +Django リリースのドキュメントよりも多くの情報を提供していることがあります. + +.. _`バージョン管理システム下にある`: http://code.djangoproject.com/browser/django/trunk/docs +.. _stored in revision control: http://code.djangoproject.com/browser/django/trunk/docs + + +.. _Where can I find Django developers for hire?: + +Django 開発者はどこで雇えますか? +--------------------------------- + +`求職中の開発者リスト`_ には,喜んであなたの力になってくれる Django 開発者 +のリストがあります. + +また,求人を http://www.gypsyjobs.com/ に出してみてもよいかもしれません. + +.. _`求職中の開発者リスト`: http://code.djangoproject.com/wiki/DevelopersForHire +.. _developers for hire page: http://code.djangoproject.com/wiki/DevelopersForHire + + +.. _Installation questions: + +インストールに関する質問 +======================== + +.. _How do I get started?: + +どこから始めたらいいですか? +---------------------------- + + #. `コードをダウンロード`_ してください. + #. Django をインストールしてください (`インストールガイド`_ を読んで下 + さい). + #. `チュートリアル`_ をやってみてください. + #. 他の `ドキュメント`_ にも目を通して下さい.何かトラブルに出会ったら, + `質問`_ してみましょう. + +.. _`コードをダウンロード`: http://www.djangoproject.com/download/ +.. _`インストールガイド`: ../install/ +.. _`チュートリアル`: ../tutorial01/ +.. _`ドキュメント`: ../index/ +.. _`質問`: http://www.djangoproject.com/community/ + +.. _`Download the code`: http://www.djangoproject.com/download/ +.. _`installation guide`: ../install/ +.. _tutorial: ../tutorial1/ +.. _documentation: ../ +.. _ask questions: http://www.djangoproject.com/community/ + +.. _How do I fix the "install a later version of setuptools" error?: + +"install a later version of setuptools" の解決方法は? +------------------------------------------------------ + +Django 配布物に入っている ``ez_setup.py`` を実行してください. + +.. _What are Django's prerequisites?: + +Django を動かすには何が必要? +----------------------------- + +Django を動かすには Python_ 2.3 以降が必要です.Django の初歩的な利用では、 +それ以外の Python ライブラリは不要です. + +開発環境を使う場合,つまり Django を試したいだけの場合は, Web サーバを別に +インストールしておく必要はありません. Django には軽量な開発用サーバがつい +てきます. +運用環境には `Apache 2`_ と mod_python_ を勧めますが, Django は WSGI_ 仕様 +に従っているので,様々なサーバフラットフォームで動作します. + +Django をデータベースと合わせて使うならデータベースエンジンも必要です. +我々は PostgreSQL_ ファンなので PostgreSQL をお勧めしますが, MySQL_ や +`SQLite 3`_ もサポートしています. + +.. _Python: http://www.python.org/ +.. _Apache 2: http://httpd.apache.org/ +.. _mod_python: http://www.modpython.org/ +.. _WSGI: http://www.python.org/peps/pep-0333.html +.. _PostgreSQL: http://www.postgresql.org/ +.. _MySQL: http://www.mysql.com/ +.. _`SQLite 3`: http://www.sqlite.org/ + + +.. _Do I lose anything by using Python 2.3 versus newer Python versions, such as Python 2.5?: + +Python 2.3 を使うのは, 2.5 のような新しいバージョンを使うよりも不利ですか? +---------------------------------------------------------------------------- + +いいえ. Django 自体は 2.3 以降全てのバージョンの Python で動作保証されてい +ます. + +もちろん, 2.3 よりも新しい Python を使っていれば,自分のコードに新しい +Python の機能を取り込めますし,Python 自体の改良によってもたらされた高速化 +や最適化の恩恵を受けられます.ただし, Django フレームワーク自体は, 2.3 で +も 2.4 や 2.5 でも同じように動作します. + +.. _Do I have to use mod_python?: + +mod_python を使わねばならないのでしょうか? +------------------------------------------- + +実際に運用する上では mod_python を使うよう勧めていますが, Django は WSGI_ +と呼ばれる構成を使っているため,必ずしも mod_python を使わねばならないわけ +ではありません. Django は WSGI を有効化したサーバと通信できます. +mod_python を使わない構成で最もよく使われる運用方式は FastCGI によるもので +す.詳しい情報は `FastCGI で Django を使う`_ を参照してください. + +また,その他の運用方法については `サーバ構成に関する wikiページ`_ を参照し +てください. + +Django を試してみたり,ローカルのコンピュータ上で開発するだけなら, Django +に付いてくる開発用 Web サーバを使ってください. + + +.. _`FastCGI で Django を使う`: ../fastcgi/ +.. _`サーバ構成に関する wikiページ`: http://code.djangoproject.com/wiki/ServerArrangements +.. _WSGI: http://www.python.org/peps/pep-0333.html +.. _`サーバ設定に関する wiki ページ`: http://code.djangoproject.com/wiki/ServerArrangements +.. _server arrangements wiki page: http://code.djangoproject.com/wiki/ServerArrangements + +.. _How do I install mod_python on Windows?: + +Windows への mod_python のインストール方法は? +---------------------------------------------- + + * Python 2.4 を使っているなら + `Python 2.4 向け mod_python の win32 ビルド`_ を入手してください. + * Python 2.4 の場合, `Windows での Django HOWTO`_ も参照してください. + * Python 2.3 なら, http://www.modpython.org/ から mod_python を取って + 来て, `Running mod_python on Apache on Windows2000`_ を読んで下さい. + * また, (Windows に限らず) `guide to getting mod_python + working`_ を読んで下さい. + +.. _`Python 2.4 向け mod_python の win32 ビルド`: http://www.lehuen.com/nicolas/index.php/2005/02/21/39-win32-build-of-mod_python-314-for-python-24 +.. _`Windows での Django HOWTO`: http://thinkhole.org/wp/2006/04/03/django-on-windows-howto/ +.. _`guide to mod_python & Python 2.3`: http://www.lehuen.com/nicolas/index.php/2005/02/21/39-win32-build-of-mod_python-314-for-python-24 +.. _`Running mod_python on Apache on Windows2000`: http://groups-beta.google.com/group/comp.lang.python/msg/139af8c83a5a9d4f +.. _`guide to getting mod_python working`: http://www.dscpl.com.au/articles/modpython-001.html + +.. _Will Django run under shared hosting (like TextDrive or Dreamhost)?: + +Django は共有ホスティングサービス (TextDrive や Dreamhost) で動きますか? +------------------------------------------------------------------------- + +`Django を使える Web ホスト`_ のページをごらん下さい. + +.. _`Django を使える Web ホスト`: http://code.djangoproject.com/wiki/DjangoFriendlyWebHosts +.. _`Django-friendly Web hosts`: http://code.djangoproject.com/wiki/DjangoFriendlyWebHosts + +.. _Should I use the official version or development version?: + +公式リリースと開発版のどちらを使うべきなのでしょうか? +------------------------------------------------------ + +Django の開発者達は毎日 Django 改良を重ねており,壊れたコードをチェックイン +しないよう上手く計らっています.私達は自分のサーバに (Subversion レポジトリ +上の) 開発中のコードを直接使っており,安定に運用できています.このことを考 +えると,一般論として.「公式の」リリースよりはより多くの機能と少ないバグを +持つ最新の開発版を使うように勧めます. + +.. _Using Django: + +Django を使う上での質問 +======================= + +.. _Why do I get an error about importing DJANGO_SETTINGS_MODULE?: + +DJANGO_SETTINGS_MODULE の import がらみのエラーがでるのはなぜ? +--------------------------------------------------------------- + +以下の点を確認してください: + + * 環境変数 DJANGO_SETTINGS_MODULE が完全指定の Python モジュール名になっ + ていますか (たとえば "mysite.settings.main"). + + * 設定モジュールは ``sys.path`` の上にありますか (``import + mysite.settings.main`` はうまくいきますか). + + * (言うまでもなく) モジュールに構文エラーはありませんか. + + * mod_python を使っていて,Django リクエストハンドラは *使っていない* + のなら, ``SetEnv`` に関わる mod_python のバグを回避する必要がありま + す. Django から何らかのモジュールを import する前に,以下のコードを + 実行してください:: + + os.environ.update(req.subprocess_env) + + (``req`` は mod_python のリクエストオブジェクトです). + +.. _I can't stand your template language. Do I have to use it?: + +テンプレート言語を好きになれません.どうしても使わないとだめですか? +-------------------------------------------------------------------- + +私達はこのテンプレートエンジンを chunky bacon 以来の傑作だと思っているんで +すが,テンプレート言語の選択というものは宗教に近いものがあるということは認 +識しています. Django では,テンプレート言語に対する制限はなんらありません. +ですから, ZPT や Cheetah などを使いたいのなら,それは自由です. + +.. _Do I have to use your model/database layer?: + +付属のモデル/データベースレイヤを使わねばならないのですか? +------------------------------------------------------------ + +いいえ,テンプレートシステムと同様,モデル/データベースレイヤはフレームワー +クの他の部分と脱カップリングしています. + +唯一の例外: 別のデータベースライブラリを使った場合には, Django の自動生成 +admin サイトを利用できなくなります. admin だけは Django のデータベースレイ +ヤとカップリングしています. + + +.. _How do I use image and file fields?: + +画像やファイルのフィールドの使い方は? +-------------------------------------- + +モデルで ``FileField`` や ``ImageField`` を使うには,いくつかのステップを踏 +む必要があります: + + #. 設定ファイル内で ``MEDIA_ROOT`` を指定します.この値は,Django がアッ + プロードされたファイルを置く場所にします (パフォーマンス上の理由から, + ファイルをデータベースに置くことはありません). ``MEDIA_URL`` をその + ディレクトリの公開 URL にします.ディレクトリは Web サーバのユーザア + カウントに対して書き込み可能にしておかねばなりません. + + #. モデルに ``FileField`` や ``ImageField`` を追加し, ``upload_to`` オ + プションを定義して, ``MEDIA_ROOT`` のどのサブディレクトリにファイル + をアップロードさせるのかを Django に教えます. + + #. データベースにい保存されるのは,ファイルの (``MEDIA_ROOT`` からの相 + 対で表した) パスだけです. Django の提供している便宜関数 + ``get__url`` を使うことになるでしょう.例えば, + ``mug_shot`` という名前の ``ImageField`` があるとすると,テンプレー + トで画像の URL を指定するには ``{{ object.get_mug_shot_url }}`` のよ + うにします. + +.. _Databases and models: + +データベースとモデルに関する質問 +================================ + +.. _How can I see the raw SQL queries Django is running?: + +Django が実行している生の SQL クエリを見られますか? +---------------------------------------------------- + +まず, ``DEBUG`` 設定を ``True`` にして Django を動かしているか確認してく +ださい.次に,以下のコードを実行します:: + + >>> from django.db import connection + >>> connection.queries + [{'sql': 'SELECT polls_polls.id,polls_polls.question,polls_polls.pub_date FROM polls_polls', + 'time': '0.002'}] + +``connection.queries`` を使えるのは ``DEBUG`` が ``True`` の時だけです.こ +の値は,クエリの実行順に辞書を並べたものです.各辞書には以下の値が入ってい +ます:: + + ``sql`` -- 生の SQL 文 + ``time`` -- SQL 文の実行にかかった時間を秒で表したもの + +``connection.queries`` には, INSERT, UPDATE, SELECT といった全ての SQL 文 +が入ります.クエリはアプリケーションがデータベースを操作する度に記録され +てゆきます. + +.. _Can I use Django with a pre-existing database?: + +既存のデータベースで Django を使えますか? +------------------------------------------ + +使えます. `古いデータベースの組み込み`_ を参照してください. + +.. _`古いデータベースの組み込み`: ../legacy_databases/ +.. _`Integrating with a legacy database`: ../legacy_databases/ + + +.. _If I make changes to a model, how do I update the database?: + +モデルを変更した場合のデータベースの更新方法は? +------------------------------------------------ + +データが消えてもかまわないのなら, ``manage.py`` ユーティリティを使って,特 +定のアプリケーションをリセットする SQL を発行できます:: + + manage.py reset appname + +この操作で, ``appname`` に関係したテーブルが削除され,再度作成されます. + +データを削除したくないのなら,手作業で ``ALTER TABLE`` 文を実行せねばなりま +せん.私達はいつもこの方法でやっています.というのも,データの扱いはとても +慎重にせねばならないので,私達は自動化を避けたいのです.とはいえ,データベー +スの更新を部分的に自動化する機能を追加すべく現在作業中です. + +.. _Do Django models support multiple-column primary keys?: + +Django のモデルは複数カラムにわたる主キーをサポートしていますか? +----------------------------------------------------------------- + +いいえ.サポートしているのは単カラムの主キーだけです. + +しかし,実践的には問題にはなりません.というのは,(``unique_together`` モデ +ルオプションを指定したり,直接データベースに制約を作ったりして) 他の制約を +課し,モデルレベルで一意性を強制できるからです.単カラムの主キーは admin イ +ンタフェースをうまく稼働させるため,例えば編集や削除対象のオブジェクトを指 +定する簡潔な手段として必要なのです. + + +.. _How do I add database-specific options to my CREATE TABLE statements, such as specifying MyISAM as the table type?: + +テーブル形式を MyISAM に指定するなど,データベース固有のオプションを CREATE TABLE 文に追加したいのですが,どうすればよいですか? +-------------------------------------------------------------------------------------------------------------------------------- + +私達は,テーブルの形式のようなデータベース固有のオプションに対応するために +Django のコードに特殊なケースを追加したくないと考えています.こうしたオプショ +ンを使いたければ, `SQL の初期データファイル`_ を作成して,その中で +``ALTER TABLE`` 文を使って自分の目的を実現してください.初期データファイル +はデータベースの中で ``CREATE TABLE`` 文の後に実行されます. + +例えば, MySQL を使っていて, MyISAM テーブルタイプを使いたい場合には,初期 +データファイルを作成して,以下のような行を挿入します:: + + ALTER TABLE myapp_mytable ENGINE=MyISAM; + +`SQL の初期データファイル`_ でも説明していますが, SQL ファイルには任意の +SQL コードを入れられるので,SQL で行なえる変更なら何でも実現できます. + +.. _`SQL の初期データファイル`: ../model_api/#providing-initial-sql-data +.. _SQL initial data file: ../model_api/#providing-initial-sql-data + +Django がメモリリークを起こしているのですが,なぜですか? +--------------------------------------------------------- + +Django に既知のメモリリークはありません. Django プロセスがメモリをどんどん +消費して,いっこうに開放する気配がない場合, ``DEBUG`` が ``True`` になって +いないか調べてみてください. ``DEBUG`` を ``True`` にすると, Django は実行 +した SQL 文の全てのコピーを保存するようになるからです. + +(クエリは ``django.db.connection.queries`` で保存されます. +`Django が実行している生の SQL クエリを見られますか?`_ を参照してください.) + +問題を解決するには, ``DEBUG`` を ``False`` にしてください. + +クエリリストを手動で消去するには,以下のように ``reset_queries()`` を呼び出 +してください:: + + from django import db + db.reset_queries() + + +admin サイトに関する質問 +======================== + +.. _`I can't log in. When I enter a valid username and password, it just brings up the login page again, with no error messages.`: + +ログインできません.正しいユーザ名とパスワードを入力したのに,エラーメッセージも出ず再度ログインページが表示されるのです. +-------------------------------------------------------------------------------------------------------------------------- + + +Django の発行するクッキーのドメインと,ブラウザに格納されたドメインが一致し +ていないため,ログインクッキーが正しく設定されないからです.以下の二つの対 +策を試してみて下さい: + + * admin 設定ファイルの ``SESSION_COOKIE_DOMAIN`` とお使いのドメインが一 + 致するように設定してください.例えば,ブラウザで + "http://www.mysite.com/admin/" にアクセスするようになっているのなら, + "myproject.settings" には ``SESSION_COOKIE_DOMAIN = 'www.mysite.com'`` + と設定せねばなりません. + + * ブラウザによっては (Firefox?) ドットの入っていないドメインからのクッ + キーを受け取ろうとしないようです.admin を "localhost" などのようなドッ + トを含まないドメインで実行しているのなら,"localhost.localdomain" や + "127.0.0.1" のように指定してアクセスしてください.また, + ``SESSION_COOKIE_DOMAIN`` もそれに合わせて変更してください. + +.. _`I can't log in. When I enter a valid username and password, it brings up the login page again, with a "Please enter a correct username and password" error.`: + +ログインできません.正しいユーザ名とパスワードを入力したところ,「正しいユーザ名とパスワードを入力してください」というエラーメッセージの表示されたログインページが表示されます. +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +ユーザネームとパスワードが本当に正しいのなら,ユーザアカウントが +``is_active`` で,かつ ``is_staff`` が ``True`` になっているか確かめて下さ +い. admin サイトにアクセスできるのは,これら二つのフィールドが共に +``True`` であるユーザだけです. + +.. _How can I prevent the cache middleware from caching the admin site?: + +キャッシュミドルウェアに admin サイトをキャッシュさせなくするにはどうすればよいですか? +--------------------------------------------------------------------------------------- + +``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` 設定を ``True`` にしてください.詳しく +は `キャッシュのドキュメント`_ を参照してください. + +.. _`キャッシュのドキュメント`: ../cache/#the-per-site-cache + +.. _How do I automatically set a field's value to the user who last edited the object in the admin?: + +admin で,フィールドの値を,オブジェクトを最後に編集したユーザの指定した値と同じにする方法は? +---------------------------------------------------------------------------------------------- + +現時点では, Django はこの操作を行う正規の方法を提供していません.しかしこ +の要望はよく出ているので,どうやって実装するかを議論しているところです.問 +題は,(現在のユーザを判定するのに) モデルレイヤと admin レイヤとリクエスト +レイヤをカップリングしたくないという点にあります.これは難しい問題です. + +`solution that doesn't require patching Django`_ というハックを提供している +人もいますが,これは正規の方法ではなく,将来うまく働かなくなる可能性があり +ます. + +.. _solution that doesn't require patching Django: http://lukeplant.me.uk/blog.php?id=1107301634 + + + +.. _How do I limit admin access so that objects can only be edited by the users who created them?: + +admin で,オブジェクトを作成したユーザだけがオブジェクトを編集できるようにアクセスを制限する方法は? +---------------------------------------------------------------------------------------------------- + +一つ前の質問の答えを見て下さい. + +.. _My admin-site CSS and images showed up fine using the development server, but they're not displaying when using mod_python.: + +開発サーバでは admin サイトの CSS や画像がうまく表示されるのに, mod_python を使うと表示されません. +---------------------------------------------------------------------------------------------------- + +「mod_python で Django を使う」というドキュメントの `admin ファイルの提供`_ + +.. _`admin ファイルの提供`: ../modpython/#serving-the-admin-files +.. _serving the admin files: ../modpython/#serving-the-admin-files + +.. _My "list_filter" contains a ManyToManyField, but the filter doesn't display.: + +"list_filter" に ManyToManyField を入れたのに,フィルタが表示されません. +------------------------------------------------------------------------- + +Django が ``ManyToManyField`` に対してフィルタを表示するのはオブジェクトが +二つ以上のときだけです. + +例えば, ``list_filter`` に ``sites`` が入っており,データベースにたった一 +つしかサイトが登録されていなければ, "Site" フィルタは表示されません. +この状況では,サイトによるフィルタは無意味だからです. + +.. _How can I customize the functionality of the admin interface?: + +admin インタフェースの機能をカスタマイズする方法は? +---------------------------------------------------- + +方法はいくつかあります.Django が自動生成する add/change フォームを利用して +楽をしたければ,モデルの ``class Admin`` の ``js`` パラメタを使ってページに +任意の JavaScript モジュールを貼り付けてください.パラメタは文字列で表した +URL からなるリストで, admin フォームに + +これはまさに admin がサーバから翻訳を取り出しているのと同じ方法です.カタロ +グをロードしたら,JavaScript から標準的な ``gettext`` インタフェースを使っ +てアクセスできるようになります:: + + document.write(gettext('this is to be translated')); + +文字列補完を行える ``ngettext`` インタフェースもあります:: + + d = { + count: 10 + }; + s = interpolate(ngettext('this is %(count)s object', 'this are %(count)s objects', d.count), d); + +``interpolate`` 関数は,固定引数による補完と名前付き補完の両方をサポートし +ています.従って,上のコードは以下のようにも書けます:: + + s = interpolate(ngettext('this is %s object', 'this are %s objects', 11), [11]); + +補完の構文は Python から借りたものです.とはいえ,この文字列補完を派手に使 +わない方がよいでしょう: 補完機能は JavaScript で動いており,中では何度も正 +規表現置換を行っています.この処理は Python の文字列補完ほど高速ではないの +で,本当に必要な場合 (例えば ``ngettext`` を使って適切な複数形表現を実現し +たい場合) だけにしてください. + +.. _Creating JavaScript translation catalogs: + +JavaScript の翻訳カタログを作成する +----------------------------------- + +JavaScript の翻訳カタログの作成と更新方法,他の Django の翻訳カタログの場合 +と同じで, {{{make-messages.py}}} ツールを使います.ただし, +``-d djangojs`` パラメタを指定してください.例えば:: + + make-messages.py -d djangojs -l de + +上の例では,ドイツ語向けの JavaScript の翻訳カタログを作成または更新してい +ます.翻訳カタログを更新したら,通常の Django 翻訳カタログと同じように, +``compile-messages.py`` を実行してください. + +.. _Specialities of Django translation: + +Django 翻訳の特徴 +================= + +``gettext`` について詳しければ, Django の翻訳機能には以下のような特徴があ +ることに気づくでしょう: + + * 文字列ドメインは ``django`` または ``djangojs`` です.この文字列ドメ + インは,共通のメッセージファイルライブラリ (通常は + ``/usr/share/locale/`` にあります) にデータを保存している他のプログラ + ムと Django のデータを区別するためです. ``django`` ドメインは, + Python とテンプレート翻訳文字列に使われ,グローバルな翻訳カタログ上に + 読み込まれます. ``djangojs`` は JavaScript だけで使うために,可能な + かぎり小さくして分けてあります. + * Django では ``gettext`` と ``gettext_noop`` しか使っていません.これ + は, Django が常に ``DEFAULT_CHARSET`` を内部的に使っているためです. + ユーザは常に utf-8 を出力せねばならないので, ``ugettext`` はあまり役 + に立たないのです. + * Django は ``xgettext`` を単体では使いません. Django では, + ``xgettext`` や ``msgfmt`` を Python ラッパ越しに使います.これは便宜 + 上の理由によります. diff --git a/index.txt b/index.txt new file mode 100644 index 0000000..ec44274 --- /dev/null +++ b/index.txt @@ -0,0 +1,155 @@ +================================= +Django オンラインドキュメント和訳 +================================= + +和訳 + Yasushi Masuda (ymasuda at ethercube dot com) +底本 + SVN trunk (0.96-pre) +追従済みリビジョン + 4781 (2007/03/23) + +必読 +---- + +`Django の概要 (Django overview) <../overview/>`__ + +`インストールガイド <../install/>`__ + +`サードパーティによる Django ディストリビューション (Third-party distributions of Django) <../distributions/>`__ + +`Django ドキュメントの読み方 (How to read the Django documentation) <../documentation/>`__ + +チュートリアル +~~~~~~~~~~~~~~ + +`はじめての Django アプリ作成,その 1: +初期化,モデル作成,データベース API <../tutorial01/>`__ + +`はじめての Django アプリ作成,その 2: +自動生成の admin サイトを探究する <../tutorial02/>`__ + +`はじめての Django アプリ作成,その 3: +公開用のインタフェースビューを作成する <../tutorial03/>`__ + +`はじめての Django アプリ作成,その 4: +簡単なフォームデータ処理と汎用ビュー <../tutorial04/>`__ + +`Django についてよくある質問 (Django FAQ) <../faq/>`__ + + +リファレンス +------------ + +`django-admin.py と manage.py (django-admin.py and manage.py) <../django-admin/>`__ + +モデル +~~~~~~ + +`モデルの作成 (Creating models) <../model-api/>`__ + +`データベース API (The database API) <../db-api/>`__ + +`トランザクション (Managing database transactions) <../transactions/>`__ + +テンプレート +~~~~~~~~~~~~ + +`テンプレート作者のための Django テンプレート言語ガイド +(Guide for HTMLauthors) <../templates/>`__ + +`Python プログラマのための Django テンプレート言語ガイド +(Guide for Python programmers) <../templates_python/>`__ + +`フォームとマニピュレータ +(Forms, fields, and manipulators) <../forms/>`__ + +`newforms ライブラリ <../newforms/>`__ + +`セッション (Sessions) <../sessions/>`__ + +`キャッシュ (Django's Cache Framework) <../cache/>`__ + +`国際化 (Internationalization) <../i18n/>`__ + +`ミドルウェア (Middlewares) <../middleware/>`__ + +`設定ファイル (Settings files) <../settings/>`__ + +`URL の設定 (URL configuration) <../url_dispatch/>`__ + +`リクエストオブジェクトとレスポンスオブジェクト +(Request and response objects) <../request_response/>`__ + +`汎用ビュー (Generic views) <../generic_views/>`__ + +`認証 (Authentication) <../authentication/>`__ + +`アドオン (Add-on applications (contrib)) <../add_ons/>`__ + + `配信フィード (Syndication feeds (RSS and Atom)) <../syndication_feeds/>`__ + + `flatpages アプリケーション <../flatpages/>`__ + + `リダイレクト (Redirects) <../redirects/>`__ + + `クロスサイトリクエストフォージェリ (CSRF) の阻止 <../csrf/>`__ + + `サイト (Sites) <../sites/>`__ + + `サイトマップ (Sitemaps) <../sitemaps/>`__ + + +運用関連 +-------- + +`mod_python で Django を使う (Using Django with mod_python) <../modpython/>`__ + +`FastCGI で Django を使う (Using Django with FastCGI) <../fastcgi/>`__ + +特殊な話題 +---------- + +`Apache での認証に Django ユーザデータベースを使う +(Authenticating against Django's user database from Apache) <../apache_auth/>`__ + +`静的ファイルの提供方法 (Serving static/media files) <../static_files/>`__ + +`e-mail の送信 (Sending e-mail) <../email/>`__ + +`データベースのサポート状況 (Notes about supported databases) <../databases/>`__ + +`古いデータベースの組み込み +(Integrating with (introspecting) a legacy database) <../legacy_databases/>`__ + +`複数のデータベースを使う (Using Multiple Databases (in multi-db branch)) <../multiple_database_support/>`__ + +`動的な PDF の生成 (Outputting PDFs dynamically) <../outputting_pdf/>`__ + +`動的な CSV の生成 (Outputting CSV dynamically) <../outputting_csv/>`__ + +`Django オブジェクトのシリアライズ (Serializing Django objects) <../serialization/>`__ + +`Django アプリケーションのテスト (Writing tests for Django applications) <../testing/>`__ + +その他 +------ + +`Django の設計思想 (Design philosophies) <../design_philosophies/>`__ + +`Django プロジェクトに協力するために +(How to contribute to Django) <../contributing/>`__ + +`Django admin CSS guide <../admin_css/>`__ + +`API の安定性 <../api_stability/>`__ + + +リリースノート +-------------- + +`バージョン 0.96 リリースノート <../release_notes_0.96/>`__ + +`バージョン 0.95 リリースノート <../release_notes_0.95/>`__ + + diff --git a/install.txt b/install.txt new file mode 100644 index 0000000..9eddcef --- /dev/null +++ b/install.txt @@ -0,0 +1,156 @@ +===================== +Django のインストール +===================== + +:revision-up-to: 4805 (release 0.96) + +このドキュメントを読めば Django を動かせるようになります. + +.. _Install Python: + +Python のインストール +===================== + +Django は Python の Web フレームワークなので Python が必要です. + +Django はバージョン 2.3 以上の Python で動作します. + +www.python.org から Python を取ってきましょう. Linux や Mac OSX を動かして +いるのなら,おそらくインストール済みのはずです. + +.. _Install Apache and mod_python: + +Apache と mod_python のインストール +=================================== + +単に Django を試してみたいだけなら,この節は読み飛ばしてかまいません. +Django には独自開発用 Web サーバがついてきます. + +Django を実運用のサイトで使いたい場合, Apache と `mod_python`_ を使って下 +さい. mod_python は mod_perl のようなもので, Python を Apache の中に埋め +込み,サーバの起動時に Python コードをメモリにロードします.コードは Apache +プロセスが生きている間ずっとメモリ上に存在するので,他のサーバ構成よりも明 +らかに高いパフォーマンスを実現します. Django の動作には Apache 2.x および +mod_python 3.x が必要です. + +mod_python をインストールしたら,設定に関する情報は +`mod_python で Django を動かす`_ を参照してください. + +何らかの理由で mod_python を使えない場合でも心配はいりません: Django は +WSGI_ 仕様に従っているので,様々なサーバプラットフォームで動作させられます. +個々のプラットフォームにおけるインストール方法の説明は +`サーバ構成に関する wiki ページ`_ を参照してください. + +.. _Apache: http://httpd.apache.org/ +.. _mod_python: http://www.modpython.org/ +.. _WSGI: http://www.python.org/peps/pep-0333.html +.. _`mod_python で Django を動かす`: ../modpython/ +.. _`サーバ構成に関する wiki ページ`: http://code.djangoproject.com/wiki/ServerArrangements +.. _How to use Django with mod_python: ../modpython/ +.. _server-arrangements wiki page: http://code.djangoproject.com/wiki/ServerArrangements + +.. _Get your database running: + +データベースを動かす +==================== + +Django のデータベース API 機能を使うのなら,データベースサーバを動かす必要 +があります. Django は PostgreSQL_ (推奨), MySQL_, および SQLite_ で動作し +ます. + +さらに,各データベースの Python バインディングをインストールしておく必要が +あります. + +* PostgreSQL を使う場合, psycopg_ パッケージ (バージョン 2 の + ``postgresql_psycopg2`` バックエンドを推奨します.バージョン 1.1 の + ``postgresql`` バックエンドも使えます) が必要です.Windows 環境なら, + 非公式の `Windows むけコンパイル済みパッケージ`_ を使って下さい. +* MySQL を使う場合は,バージョン 1.2.1p2 以降の MySQLdb_ が必要です. +* SQLite を使う場合は pysqlite_ が必要です.バージョン 2.0.3 以上を使って下 + さい. + +.. _PostgreSQL: http://www.postgresql.org/ +.. _MySQL: http://www.mysql.com/ +.. _Django's ticket system: http://code.djangoproject.com/report/1 +.. _psycopg: http://initd.org/projects/psycopg +.. _`Windows むけコンパイル済みパッケージ`: http://stickpeople.com/projects/python/win-psycopg/ +.. _compiled Windows version: http://stickpeople.com/projects/python/win-psycopg/ +.. _MySQLdb: http://sourceforge.net/projects/mysql-python +.. _SQLite: http://www.sqlite.org/ +.. _pysqlite: http://initd.org/tracker/pysqlite + +.. _Install the Django code: + +Django コードのインストール +=========================== + +公式リリース版を入れる場合と,最新の開発バージョンを入れる場合では, +インストール方法の説明が少し違います. + +どちらの方法も難しくはありません. + +.. _Installing the official version: + +公式リリースのインストール +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + 1. `ディストリビューション固有の注意 <../distributions/>`_ を調べて,自 + 分のプラットフォーム/ディストリビューションで公式の Django パッケー + ジやインストーラが提供されていないか調べます.ディストリビューション + 固有の配布パッケージは,たいてい依存関係のあるパッケージを自動的にイ + ンストールしてくれたり,パスの更新を行ってくれたりします. + + 2. `ダウンロードページ`_ から,最新版の Django をダウンロードします. + + 3. ダウンロードしたファイルを展開します + (例: ``tar xzvf Django-NNN.tar.gz`` + + 4. 展開先のディレクトリに移ります (例: ``cd Django-NNN``) + + 5. ``sudo python setup.py install`` を実行します. + + +上のコマンドを実行すると, Django は Python インストールディレクトリの +``site-packages`` ディレクトリ下にインストールされます. + +.. _distribution specific notes: ../distributions/ + +.. _Installing the development version: + +開発バージョンのインストール +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Django のコードを更新して最新のバグフィクスや改良を適用したいのなら,以下の +説明に従って開発バージョンをインストールしてください. + +1. Subversion_ がインストールされていることを確認してください. +2. Django のコードを Python の ``site-packages`` ディレクトリにチェックアウ + トします. Linux / Mac OSX / Unix では,以下のコマンドを実行します:: + + svn co http://code.djangoproject.com/svn/django/trunk/ django_src + ln -s `pwd`/django_src/django /usr/lib/python2.3/site-packages/django + + (上の作業では,使っている Python のバージョンに合わせて ``python2.3`` を + 適宜読み変えて下さい) + + Windows では以下のようにします:: + + svn co http://code.djangoproject.com/svn/django/trunk/django c:\Python24\lib\site-packages\django + +3. ``django_src/django/bin/django-admin.py`` ファイルを,システムパス上に + コピーします.例えば, Unix では ``/usr/local/bin`` , Windows では + ``C:\Python24\Scripts`` です.この作業は, ``django-admin.py`` を任意の + ディレクトリで実行するときに,毎回フルパスを入れなくてもよくするためのも + のです. + +``python setup.py install`` を *実行する必要はありません* . +``python setup.py install`` は,ステップ 2 および 3 を実行するためのコマン +ドだからです. + +Django のソースコードを更新する際には, ``django`` ディレクトリで +``svn update`` を実行してください.実行すると, Subversion が更新部分を自動 +的にダウンロードします. + +.. _`ダウンロードページ`: http://www.djangoproject.com/download/ +.. _`download page`: http://www.djangoproject.com/download/ +.. _Subversion: http://subversion.tigris.org/ diff --git a/legacy_databases.txt b/legacy_databases.txt new file mode 100644 index 0000000..9c34d58 --- /dev/null +++ b/legacy_databases.txt @@ -0,0 +1,101 @@ +================================== +古いデータベースの組み込み +================================== + +:revision-up-to: 4805 (release 0.96) + +Django が最も得意とするのは新たなアプリケーションですが,古いデータベースの +組み込みも可能です. Django には組み込み作業を可能な限り自動化するための二 +つのユーティリティが付属しています. + +このドキュメントでは,読者は `公式チュートリアル`_ でカバーされている +Django の基礎を良く知っているものと仮定しています. + +.. _`公式チュートリアル`: ../tutorial01/ +.. _official tutorial: ../tutorial1/ + +.. _Give Django your database parameters: + +Django にデータベースパラメタを指定する +======================================= + +まず,データベースへの接続パラメタとデータベース名を Django に指示する必要 +があります. `設定ファイル`_ の以下の設定を編集してください: + + * `DATABASE_NAME`_ + * `DATABASE_ENGINE`_ + * `DATABASE_USER`_ + * `DATABASE_PASSWORD`_ + * `DATABASE_HOST`_ + * `DATABASE_PORT`_ + +.. _`設定ファイル`: ../settings/ +.. _DATABASE_NAME: ../settings/#database-name +.. _DATABASE_ENGINE: ../settings/#database-engine +.. _DATABASE_USER: ../settings/#database-user +.. _DATABASE_PASSWORD: ../settings/#database-password +.. _DATABASE_HOST: ../settings/#database-host +.. _DATABASE_PORT: ../settings/#database-port + +.. _settings file: + ../settings/ +.. DATABASE_NAME: + ../settings/#database-name +.. DATABASE_ENGINE: + ../settings/#database-engine +.. DATABASE_USER: + ../settings/#database-user +.. DATABASE_PASSWORD: + ../settings/#database-password +.. DATABASE_HOST: + ../settings/#database-host +.. DATABASE_PORT: + ../settings/#database-port + +.. _Auto-generate the models: + +モデルの自動生成 +================ + +Django には,既存のデータベースにイントロスペクションを行ってモデルを生成で +きるユーティリティが付属しています.出力を見るには以下のコマンドを実行しま +す:: + + django-admin.py inspectdb --settings=path.to.settings + +標準の Unix 出力リダイレクションを使って,この内容をファイルに保存しておき +ます:: + + django-admin.py inspectdb --settings=path.to.settings > appname.py + +この機能はショートカット目的で,正しいモデル生成を行うためのものではありま +せん.詳しくは `django-admin.py のドキュメント`_ を参照してください. + +モデルを削除し終えたら,モジュールをアプリケーションの ``models.py`` +に入れ,アプリケーションを収めているパッケージ内に配置し, +``INSTALLED_APPS`` 設定にアプリケーションを追加しておきます. + +.. _django-admin.py のドキュメント: ../django-admin/ +.. _django-admin.py documentation: ../django_admin/ + +.. _Install the core Django tables: + +Django のコアデータテーブルのインストール +========================================= + +次に, ``django-admin.py syncdb`` コマンドを実行して, Django のコアデータ +テーブルをデータベースにインストールします:: + + django-admin.py syncdb --settings=path.to.settings + + +.. _See whether it worked: + +うまく動作するか確認する +======================== + +これだけです. Django データベース API を使ってアプリケーションのデータにア +クセスしたり, Django admin サイトでオブジェクトを編集してみたりしてくださ +い. + + diff --git a/middleware.txt b/middleware.txt new file mode 100644 index 0000000..774ebf0 --- /dev/null +++ b/middleware.txt @@ -0,0 +1,257 @@ +============ +ミドルウェア +============ + +:revision-up-to: 4805 (release 0.96) + +ミドルゥェア (Middleware) とは, Django のリクエスト/レスポンス処理に対する +フックの集まりです.ミドルウェアは Django の入出力を操作するための軽量かつ +低水準な「プラグイン」システムです. + +各ミドルウェアコンポーネントはそれぞれ特定の機能を担っています.例えば, +Django には ``XViewMiddleware`` ミドルウェアコンポーネントがありますが,こ +れは全ての ``HEAD`` リクエストに対して ``"X-View"`` HTTP ヘッダを追加します. + +このドキュメントでは, Django についてくる全てのミドルウェアコンポーネント +の使用法と,自分で新たにミドルウェアを作る方法を説明します. + + +.. _Activating middleware: + +ミドルウェアの有効化 +==================== + +ミドルウェアコンポーネントを有効化するには,Django 設定ファイルの +``MIDDLEWARE_CLASSES`` リストにコンポーネントを追加します. +コンポーネント名は文字列で指定し,ミドルウェアのクラス名を完全な Python パ +スで表します.例えば, ``django-admin.py startproject`` が生成するデフォル +トの設定ファイルにある ``MIDDLEWARE_CLASSES`` は以下のようになっています:: + + MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.middleware.doc.XViewMiddleware', + ) + +Django は ``MIDDLEWARE_CLASSES`` に指定された順番でミドルウェアを適用してい +きます.ただし,応答および例外ミドルウェアの場合は逆順に適用します. + +Django をインストールする上で,必ずしもミドルウェアを指定しておく必要はあり +ません -- 望むなら ``MIDDLEWARE_CLASSES`` は空でもよいのです.とはいえ, +``CommonMiddleware`` を使うように強く勧めます. + +.. _Available middleware: + +利用できるミドルウェア +====================== + +django.middleware.cache.CacheMiddleware +--------------------------------------- + +サイト全体にわたるキャッシュを有効にします.キャッシュを有効にすると, +Django の管理下にあるページは ``CACHE_MIDDLEWARE_SECONDS`` 設定に定義した時 +間のキャッシュされます.`キャッシュのドキュメント`_ を参照してください. + +.. _`キャッシュのドキュメント`: ../cache/#the-per-site-cache +.. _`cache documentation`: ../cache/#the-per-site-cache + +django.middleware.common.CommonMiddleware +----------------------------------------- + +リクエスト処理に完全主義者むけの便宜機能を追加するミドルウェアです. + +* ``DISALLOWED_USER_AGENTS`` に設定されたユーザエージェントからのアクセスを + 禁止します. ``DISALLOWED_USER_AGENTS`` には文字列のリストを指定します. + +* ``APPEND_SLASH`` および ``PREPEND_WWW`` に基づいて URL の書き換えを行いま + す. ``APPEND_SLASH`` が ``True`` であれば,末尾にスラッシュのない URL は + スラッシュ付きの URL にリダイレクトします. ただし,パスの最後の要素がピ + リオドを含む場合にはスラッシュを追加しません.このため, ``foo.com/bar`` + は ``foo.com/bar/`` にリダイレクトされますが, ``foo.com/bar/file.txt`` + は変更されず,そのまま次のレイヤに渡されます. + + ``PREPEND_WWW`` が ``True`` であれば,先頭に, "www." のない URL は先頭に + "www." を付けた URL にリダイレクトします. + + それぞれのオプションは URL を正規化するためのものです.これは, URL + (Uniform Resorce Location) がただひとつの,真にただひとつの場所 + (Location) を表すべきであるという哲学に基づいています.技術的には, + ``foo.com/bar`` は ``foo.com/bar/`` とは別物です -- 例えば,検索エンジン + はこの二つの URL を別々の URL として扱うかもしれません -- ですから, URL + を正規化しておく方が得策なのです. + +* ``USE_ETAGS`` 設定に基づいて ETag を処理します. ``USE_ETAGS`` を + ``True`` に設定すると, Django は各リクエストごとにページ内容の MD-5 ハッ + シュを計算して ETag にし,必要なら ``Not Modified`` 応答を返します. + +django.middleware.doc.XViewMiddleware +------------------------------------- + +``INTERNAL_IPS`` 設定に定義されている IP アドレスから来た HEAD リクエストに +対してカスタムの ``X-View`` HTTP ヘッダを送信します.このミドルウェアは +Django の自動ドキュメントシステムで使われています. + +django.middleware.gzip.GZipMiddleware +------------------------------------- + +gzip 圧縮を受け付けるブラウザ (最近のほとんどのブラウザがそうです) 向けに, +コンテンツを圧縮して送ります. + +django.middleware.http.ConditionalGetMiddleware +----------------------------------------------- + +条件付き GET 操作を処理します.レスポンスに ``ETag`` または +``Last-Modified`` ヘッダがあり,リクエストに ``If-None-Match`` または +``If-Modified-Since`` がある場合,レスポンスは HttpNotModified に置き換えら +れます. + +また, HEAD リクエストに対する応答から本体部分を除去し, ``Date`` および +``Content-Length`` 応答ヘッダを設定します. + +django.middleware.http.SetRemoteAddrFromForwardedFor +---------------------------------------------------- + +``request.META['HTTP_X_FORWARDED_FOR']`` が設定されていた場合,その値に基づ +いて ``request.META['REMOTE_ADDR']`` をセットします.サーバがリバースプロキ +シの向こうにあるためにリクエストの ``REMOTE_ADDR`` が ``127.0.0.1`` にセッ +トされてしまう場合に便利です. + +**注意事項:** このミドルウェアは ``HTTP_X_FORWARDED_FOR`` を検証 +**しません** ``HTTP_X_FORWARDED_FOR`` を自動的に設定するリバースプロキシ +を経由していない場合には,このミドルウェアを使ってはなりません.なぜなら, +``HTTP_X_FORWARDED_FOR`` の値はだれでも簡単に偽装できるので,このミドルウェ +アが ``REMOTE_ADDR`` に基づいて ``HTTP_X_FORWARDED_FOR`` を設定すると,誰も +が "偽の" IP アドレスを名乗れてしまうからです.このミドルウェアを使ってよい +のは, ``HTTP_X_FORWARDED_FOR`` の値を完全に信用できる場合だけです. + + +django.contrib.sessions.middleware.SessionMiddleware +---------------------------------------------------- + +セッションのサポートを有効にします. `セッションのドキュメント`_ も参照して +ください. + +.. _`セッションのドキュメント`: ../sessions/ +.. _`session documentation`: + ../sessions/ + +django.contrib.auth.middleware.AuthenticationMiddleware +------------------------------------------------------- + +入力される ``HttpRequest`` オブジェクト全てに,現在ログインしているユーザを +表す ``user`` 属性を追加します. `Web リクエストの認証`_ を参照してください. + +.. _`Web リクエストの認証`: + ../authentication/#authentication-in-web-requests +.. _Authentication in Web requests: + ../authentication/#authentication-in-web-requests + + +django.middleware.transaction.TransactionMiddleware +--------------------------------------------------- + +リクエスト/レスポンス処理フェイズに commit と rollback をバインドします. +あるビュー関数の実行に成功した場合に commit を,例外を送出して失敗した場合 +には rollback を行わせます. + +このミドルウェアでは,スタック中の順番が重要になります.このミドルウェアの +外で動作する他のミドルウェアモジュールは,Django のデフォルトの挙動,すなわ +ち commit-on-save モードで動作します.このミドルウェアの内側にある (スタッ +クの後ろに位置している) ミドルウェアは,ビュー関数と同じトランザクション制 +御下に置かれます. + +`トランザクション管理のドキュメント`_ を参照してください. + +.. _`トランザクション管理のドキュメント`: ../transactions/ +.. _`transaction management documentation`: ../transactions/ + + +.. _Writing your own middleware: + +ミドルウェアを自作する +====================== + +ミドルウェアの自作は簡単です.各ミドルウェアコンポーネントは,以下のメソッ +ドを少なくとも一つ定義しているような単一の Python クラスです: + +process_request +--------------- + +インタフェース: ``process_request(self, request)`` + +``request`` は ``HttpRequest`` オブジェクトです.このメソッドはリクエストご +とに Django がどのビューを実行するか決定する前に呼び出されます. + +``process_request()`` は ``None`` または ``HttpResponse`` オブジェクトのい +ずれかを返さねばなりません. ``None`` を返した場合, Django はリクエストの +処理を継続し,他のミドルウェアや適切なビューを実行します. ``HttpResponse`` +オブジェクトを返した場合, Django は他のミドルウェアやビューを呼び出さず, +その ``HttpResponse`` オブジェクトを応答として返します. + +process_view +------------ + +インタフェース: ``process_view(self, request, view_func, view_args, view_kwargs)`` + +``request`` は ``HttpRequest`` オブジェクトです. ``view_func`` は Django +がビュー関数としてこれから呼び出そうとしている Python の関数です, (実際の +関数オブジェクトで,関数名を表す文字列ではありません). ``view_args`` には +ビューに渡されることになる固定引数が, ``view_kwargs`` にはビューに渡される +ことになるキーワード引数の辞書が入っています. ``view_args`` と +``view_kwargs`` のいずれにも,ビューの第一引数 (``request``) は入っていませ +ん. + +``process_view()`` は Django がビュー関数を呼び出す直前に呼び出されます.こ +の関数は ``None`` または ``HttpResponse`` オブジェクトを返さねばなりません. +``None`` を返した場合, Django は処理を継続し,他のミドルウェアの +``process_view()`` を試した後,適切なビュー関数を呼び出します. +``HttpResponse`` オブジェクトを返した場合, Django はそれ以上他のミドルウェ +アやビューを呼び出さず,その ``HttpResponse`` オブジェクトを応答として返し +ます. + +process_response +---------------- + +インタフェース: ``process_response(self, request, response)`` + +``request`` は ``HttpRequest`` オブジェクトです. ``response`` は Django の +ビュー関数の返す ``HttpResponse`` オブジェクトです. + +``process_response()`` は ``HttpResponse`` オブジェクトを返さねばなりません. +渡された ``response`` オブジェクトを変更して返しても, +新たに ``HttpResponse`` オブジェクトを生成して返してもかまいません. + +process_exception +----------------- + +インタフェース: ``process_exception(self, request, exception)`` + +``request`` は ``HttpRequest`` オブジェクトです. ``exception`` はビュー関 +数の送出した ``Exception`` オブジェクトです. + +Django はビューが例外を送出した際に ``process_exception()`` を呼び出します. +``process_exception()`` は ``None`` または ``HttpResponse`` オブジェクトの +いずれかを返さねばなりません. ``HttpResponse`` オブジェクトを返した場合, +その応答をそのままブラウザに返します.それ以外の場合,デフォルトの例外処理 +を起動します. + + +.. _Guidelines: + +ガイドライン +------------ + + * ミドルウェアのクラスはサブクラスでなくてもかまいません. + + * ミドルウェアのクラスはPython のモジュールパス上のどこにでも置けます. + Django にとって必要なのは ``MIDDLEWARE_CLASSES`` にクラスへのパスが + 指定されていることだけです. + + * Django で使えるミドルウェアを参考にしてください.Django ミドルウェア + のデフォルトの置場は ``django/middleware/`` です.ただし,セッション + ミドルウェアは ``django/contrib/sessions`` にあります. + + * 自分の書いたミドルウェアコンポーネントが他の人にとっても有用だと思っ + たなら,ぜひコミュニティにコントリビュートしてください!知らせてくだ + されば, Django に追加するか検討します. diff --git a/model-api.txt b/model-api.txt new file mode 100644 index 0000000..45f91c3 --- /dev/null +++ b/model-api.txt @@ -0,0 +1,2086 @@ +======================= +モデル API リファレンス +======================= + +:revision-up-to: 4805 (release 0.96) + +モデルとは,サイトを構成するデータの,ただ一つかつ最終的なデータソースを指 +します.モデルには,保存したいデータに不可欠なデータフィールドと,その振舞 +いが収められています.一般的に,各モデルは単一のデータベーステーブルに対応 +づけられています. + +基本として,まず以下のことを知っておきましょう: + + * 各モデルは Python のクラスで, ``django.db.models.Model`` のサブクラ + スになります. + * モデルの各属性値は,データベース上のあるフィールドを表現します. + * モデルのメタデータ (フィールドで表現されない情報) は ``Meta`` と呼ば + れる内部クラスに配置します. + * Django の admin サイトで使われるメタデータは ``Admin`` と呼ばれる内部 + クラスに配置します. + * これらの情報をもとに, Django はデータベース API を自動生成します. + API については `データベース API リファレンス`_ で解説します. + +このドキュメントを理解する上で, `モデル例の公式リポジトリ`_ +が参考になるでしょう. (Django のソース配布物中では,これらの例は +``tests/modeltests`` ディレクトリに収められています.) + +.. _`モデル例の公式リポジトリ`: + ../models/ +.. _`データベース API リファレンス`: ../db-api/ + +.. _Quick example: + +簡単な例 +======== + +以下のモデル例では, ``first_name`` および ``last_name`` というフィールドを +持った ``Person`` を定義しています:: + + from django.db import models + + class Person(models.Model): + first_name = models.CharField(maxlength=30) + last_name = models.CharField(maxlength=30) + +``first_name`` と ``last_name`` はモデルの *フィールド (fields)* です.各 +フィールドはクラス属性として定義され,各属性がデータベースのカラムに対応し +ます. + +上の ``Person`` モデルは,以下のようなデータベーステーブルを生成します:: + + CREATE TABLE myapp_person ( + "id" serial NOT NULL PRIMARY KEY, + "first_name" varchar(30) NOT NULL, + "last_name" varchar(30) NOT NULL + ); + +以下に技術的な注意点を示します: + + * テーブルの名前, ``myapp_person`` はモデルのメタデータから自動的に導 + 出したものですが,オーバライドもできます.後述の `テーブル名`_ を参照 + してください. + * ``id`` は自動的に追加されますが,この挙動もまたオーバライドできます. + `自動的な主キーフィールド`_ を参照してください. + * この例の ``CREATE TABLE`` SQL 文は PostgreSQL の書式で書かれています + が, Django は `設定ファイル`_ に指定されたデータベースバックエンド向 + けの SQL を使います. + +.. _`設定ファイル`: ../settings/ +.. _settings file: ../settings/ + + +.. _Fields: + +フィールド +========== + +モデルで最も重要であり,かつモデル定義で最小限必要な部分は,モデル内が定義 +しているデータベースフィールドのリストです.フィールドはクラスの属性として +定義されています. + +例を示します:: + + class Musician(models.Model): + first_name = models.CharField(maxlength=50) + last_name = models.CharField(maxlength=50) + instrument = models.CharField(maxlength=100) + + class Album(models.Model): + artist = models.ForeignKey(Musician) + name = models.CharField(maxlength=100) + release_date = models.DateField() + num_stars = models.IntegerField() + +.. _Field name restrictions: + +フィールド名の制約 +------------------ + +Django がモデルのフィールド名に課している制約は二つしかありません: + + 1. フィールド名は Python の予約語であってはなりません.さもなければ + Python のシンタクスエラーを引き起こすからです.例えば:: + + class Example(models.Model): + pass = models.IntegerField() # 'pass' は予約語です! + + 2. フィールド名には二つ以上の連続するアンダースコアを入れてはなりません. + なぜなら,Django のクエリ照合構文で使われているからです.例えば:: + + class Example(models.Model): + foo__bar = models.IntegerField() # 'foo__bar' に '__' が入っています! + +フィールドの名前は必ずしもデータベースのカラム名と一致していなくてもよいの +で,これらの制約は回避可能です.詳しくは後述の `db_column`_ を参照してくだ +さい. + +``join`` や ``where``, ``select`` のような SQL の予約語は,モデルのフィール +ド名に使っても *かまいません* .というのも,Django はいかなる SQL クエリ文 +でも全てのデータベーステーブル名やカラム名をエスケープするからです.エスケー +プにはデータベースエンジン固有のクオートシンタクスを使います. + + +.. _Field types: + +フィールドのタイプ +------------------ + +モデルの各フィールドは適切な ``Field`` クラスのインスタンスにせねばなりませ +ん. Django はフィールドクラス型を以下のいくつかの判定に使います: + + * データベースのカラム型 (``INTEGER``, ``VARCHAR`` など). + * Django の admin サイトで使うウィジェットの選択 + (````, ```` (一行の入力フィールド) で表現されます. + +``CharField`` には ``maxlength`` という必須の引数があります.この引数はフィー +ルドの (文字数で表した) 最大長です. ``maxlength`` への制約はデータベースと +Django 内の検証の両方のレベルで行われます. + +``CommaSeparatedIntegerField`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +カンマで区切った整数からなるフィールドです. ``CharField`` と同じく, +``maxlength`` 引数が必要です. + +``DateField`` +~~~~~~~~~~~~~ + +日付フィールドです.オプションの引数がいくつかあります: + + ================= ==================================================== + 引数 説明 + ================= ==================================================== + ``auto_now`` オブジェクトを保存する度に,その時の時刻を自動的に設 + 定します. "last-modified" タイムスタンプの実現に便 + 利です.この値はオーバライドできるデフォルト値ではな + く, *常に* 現在の日付になるので注意してください. + + ``auto_now_add`` オブジェクトを生成した時の時刻を自動的に設定します. + タイムスタンプの生成に便利です.この値はオーバライド + できるデフォルト値ではなく, *常に* 現在の日付になる + ので注意してください. + ================= ==================================================== + +admin では, JavaScript のカレンダーと 「今日」へのショートカットのついた +```` として表現されます. + +``DateTimeField`` +~~~~~~~~~~~~~~~~~ + +日付と時刻のフィールドです. ``DateField`` と同じオプションを取ります. + +admin では JavaScript のショートカットのついた ```` +フィールドで表現されます. + +``EmailField`` +~~~~~~~~~~~~~~ + +値が有効な e-mail アドレスであるかチェックする ``CharField`` です.このフィー +ルドには ``maxlength`` を指定できません. ``maxlength`` は自動的に 75 にセッ +トされるからです. + +``FileField`` +~~~~~~~~~~~~~ + +ファイルアップロードのためのフィールドです. + +必須の引数, ``upload_to`` があります.これはファイルのアップロード先となる, +ローカルのファイルシステム上のパスです.パスには +`strftime によるフォーマット`_ を入れてもよく,(ディレクトリがアップロード +されたファイルであふれないように) ファイルのアップロード日時を使って保存先 +を書き換えられます. + +admin では, ```` (ファイルアップロードウィジェット) +で表現されます. + +モデル中で ``FileField`` や ``ImageField`` (下記参照) を使うには,以下のよう +なステップが必要です: + + 1. Django にアップロードされたファイルを保存させたい場所のフルパス + を設定ファイル中の ``MEDIA_ROOT`` に指定します.(パフォーマンス + 上の理由から,アップロードされたファイルはデータベースに保存され + ません.) 保存場所への公開 URL を ``MEDIA_URL`` に指定します. + ディレクトリは Web サーバのユーザアカウントによって書き込み可能 + であるか確認してください. + + 2. ``FileField`` や ``ImageField`` をモデルに定義します.このとき, + ``upload_to`` オプションを指定して, ``MEDIA_ROOT`` 下のサブディ + レクトリのどこにアップロードされたファイルを置くべきかを Django + に教えます. + + 3. データベースに保存されるのはファイルへのパス (``MEDIA_ROOT`` か + らの相対) です.Django の提供している ``get__url`` 関 + 数を使うことになるでしょう.例えば, ``mug_shot`` という名前の + ``ImageField`` があれば,画像への絶対 URL は + ``{{ object.get_mug_shot_url }}`` で取得できます. + +例えば, ``MEDIA_ROOT`` を ``'/home/media'`` にして, ``upload_to`` を +``'photos/%Y/%m/%d'`` に設定したとします. ``upload_to`` の ``'%Y/%m/%d'`` +の部分は strftime と同じフォーマット文字を使っています.すなわち, ``'%Y'`` +が 4 桁の年号, ``'%m'`` が 2 桁の月, ``'%d'`` が 2 桁の日を表します. +従って,ファイルを 2007 年の 1 月 15 日にアップロードすると, +``/home/media/photos/2007/01/15`` に保存されることになります. + +ファイルのアップロードを処理するときには,常にアップロード先の場所やアップ +ロードされるファイルに注意して,セキュリティホールを避けるようにしてくださ +い. *アップロードされる全てのファイルをチェックして* ,予想外のファイルが +アップロードされないようにしましょう.例えば,バリデーションを行わずに Web +サーバのドキュメントルート下へのファイルのアップロードを盲目的に受け入れる +と,そこに誰かが CGI や PHP スクリプトをアップロードして,あなたのサイト上 +の URL を訪問した人にスクリプトを実行させられてしまいます.そんなことを許し +てはなりません. + +.. _`strftime によるフォーマット`: + http://www.python.jp/doc/release/lib/module-time.html#l2h-1941 + +``FilePathField`` +~~~~~~~~~~~~~~~~~ + +ファイルシステム上のあるディレクトリ下のファイル名だけを選べるようになって +いるフィールドです. 3 つの特別な引数があり,そのうち最初の一つは必須です: + + =============== ======================================================= + 引数 説明 + =============== ======================================================= + ``path`` 必須です. ``FilePathField`` が選択肢を作成するための + ディレクトリへの絶対パスです.例: ``"/home/images"`` + + ``match`` オプションです.正規表現を表す文字列で, + ``FilePathField`` がファイル名のフィルタに使います.正 + 規表現はフルパスではなくファイル名に適用されるので注意 + してください. 例: ``"foo.*\.txt^"`` は ``foo23.txt`` + にはマッチしますが, ``bar.txt`` や ``foo23.gif`` には + マッチしません. + + ``recursive`` オプションです. ``True`` または ``False`` です.デフォ + ルトは ``False`` で,``path`` のサブディレクトリを含め + るかどうかを指定します. + =============== ======================================================= + +もちろん,これらの引数を組み合わせて使ってもかまいません. + +よくある勘違いは, ``match`` がファイル名ではなくフルパスに適用されると思っ +てしまうことです.以下の例:: + + FilePathField(path="/home/images", match="foo.*", recursive=True) + +は ``/home/images/foo.gif`` にはマッチしますが,ファイル名本体 (``foo.gif`` +や ``bar.gif``) にマッチするため, ``/home/images/foo/bar.gif`` にはマッチ +しません. + +``FloatField`` +~~~~~~~~~~~~~~ + +浮動小数点数です.二つの **必須の** 引数があります: + + ====================== ============================================== + 引数 説明 + ====================== ============================================== + ``max_digits`` 数字の表現に使える最大桁数です. + + ``decimal_places`` 小数部の最大桁数です. + ====================== ============================================== + +例えば,小数点以下 2 桁までの精度を持ち,最大 999 まで表現できる値を保存す +るには:: + + models.FloatField(..., max_digits=5, decimal_places=2) + +のようにします.10 億までの値を表現でき,小数点以下 10 桁までの精度をもつ値 +を保存するには:: + + models.FloatField(..., max_digits=19, decimal_places=10) + +のようにします. + +admin では, ```` (一行の入力フィールド) で表現されます. + +``ImageField`` +~~~~~~~~~~~~~~ + +``FileField`` に似ていますが,アップロードされたオブジェクトが有効なイメー +ジかどうか検証します.二つのオプション引数, ``height_field`` および +``width_field`` をとり,これらの値が設定されている場合には,モデルのインス +タンスを保存するときに画像の高さと幅も同時に保存します. + +`Python Imaging Library`_ が必要です. + +.. _Python Imaging Library: http://www.pythonware.com/products/pil/ + +``IntegerField`` +~~~~~~~~~~~~~~~~ + +整数です. + +admin では, ```` (一行の入力フィールド) で表現されます. + +``IPAddressField`` +~~~~~~~~~~~~~~~~~~ + +IP アドレスを 文字列形式で表したもの (i.e. "24.124.1.30") です. + +admin では, ```` (一行の入力フィールド) で表現されます. + +``NullBooleanField`` +~~~~~~~~~~~~~~~~~~~~ + +``BooleanField`` と, 同じですが, ``NULL`` を選択肢に使えます. +``null=True`` の ``BooleanField`` の代わりに使って下さい. + +admin では,「不明」 ("Unknown") 「はい」 ("Yes"),「いいえ」 ("No") の選択 +肢をもつ ```` (一行の入力フィールド) +で表現されます. + +``SmallIntegerField`` +~~~~~~~~~~~~~~~~~~~~~ + +``IntegerField`` と同様ですが,ある範囲以下 (データベース依存です) の値しか +使えません. + +``TextField`` +~~~~~~~~~~~~~ + +長いテキストのためのフィールドです. + +admin では, ``