2008年6月発売ということもあり、対象のDjangoバージョンが0.9.6となっている。 適宜読み替えながら、進めている。(今回で言えば、mimetypeではなくcontent_typeを使う等)
Django概要
Webアプリケーションフレームワーク
- 動的なWebアプリケーションを開発する上で不可欠なロジックをライブラリ化しまとめたもの
- HTTPリクエスト処理
- フォームデータの検証
- セッションの管理
- ユーザーの認証
- データベースバックエンドとのやりとり
- テンプレートを使ったコンテンツのレンダリング
- メリット
- 詳細なロジックの実装から開放され、最小限のコードで高機能なWebアプリケーションを開発できる
- 動的なWebアプリケーションを開発する上で不可欠なロジックをライブラリ化しまとめたもの
ミドルウェア
すべてのリクエストやレスポンスに対して一律の処理を行いたい場合に利用
- セッション管理や最終更新時刻等をヘッダに追加したり・・・等
Djangoの認証の仕組みもミドルウェア
- 背後には組み込みの認証ミドルウェアがあり、リクエストヘッダとデータベースを 使ったユーザー認証を実現している
プロジェクト
- アプリケーションを複数のWebサイトで共有して使う場合、 Webサイトごとに使うアプリケーションやデータの置き場所を設定する必要がある。 データベースを利用する場合、サイトごとにバックエンドのデータベースを切り分けたい 場合もある。プロジェクトはそうしたサイトごとの設定を行うためのパッケージ
Djangoの設計哲学
- ルースカップリング
- ソフトウェアを構成する各コンポーネントがお互いに依存しないように設計されることを指す
- django.templateパッケージはDjangoの動作に必須ではなく、他のテンプレートシステムと置き換えて利用できる →ルースカップリング
タイトコヒージョン
- ソフトウェアの各コンポーネントが、ソフトウェアの特定の機能を集約的に担っていることを指す
- Djangoのテンプレート関連の機能はすべてdjango.templateというパッケージに集約されている →タイトコヒージョン
Python的であること
- HTTPレスポンスデータのほぼすべての情報を辞書型のAPIで直接操作可能
- レスポンスデータとして、ファイルAPI、イテレータAPI、文字列化メソッドの いずれかを備えたオブジェクトならなんでも指定できる
Djangoビュー
- 関数の第一引数に必ずリクエストオブジェクトを取る
- ユーザーから送信されたHTTPリクエストのさまざまな情報を取り出せる
def hello(request): return HttpResponse("Hello World")
- 文字列を渡して、このままreturn文で返している
これによってWebサーバーは、ユーザーに対してHTTP状態コード200(OK)と messageの中のコンテンツを返す
DjangoはURLのパターンを検索するときに、先頭のスラッシュを取り除く
- ^greet/$は、/greet/というURLに一致
レスポンスの制御:plaintextのコンテンツを返す
- コンテンツタイプのデフォルトはtext/htmlだが、mimetypeオプションで変更可能 →Django1.7以降ではcontent_type
def plaintext_time(request): from time import ctime return HttpResponse(ctime(), minetype="text/plain") from django.http import HttpResponse, Http404, HttpResponseForbidden def hello_error(request): """Simply raise Http404 """ raise Http404 def forbidden_page(request): """Simply returns 403 Forbidden code. """ return HttpResponseForbidden()
リクエストオブジェクトからデータを取り出す
- ユーザーエージェントから送信されるHTTPリクエストには、様々な情報が組み込まれている
- 認証ヘッダ、アクセス元のユーザーエージェントタイプ、IPアドレス等
- ビューの第一引数であるrequestからアクセスできる
属性 | 概要 |
---|---|
request.path_info | リクエスト先のパス |
request.scheme | HTTPヘッダのリクエストスキーム(http or https) |
request.body | HTTPボディ |
- request.META属性
def your_ip_address(request): """Displays source IP address of request """ return HttpResponse(request.META['REMOTE_ADDR'], content_type="text/plain")
- GETデータとPOSTデータ
- /formdata/から呼び出されるビューを以下のように定義
- ビュー内でgiven_nameやfamily_nameといった値にアクセスできる
<html> <body> <form action="http://localhost:8000/formdata/" method="GET"> <p>Given name<input name="given_name" type="text"></p> <p>Family name<input name="family_name" type="text"></p> <p><input type="submit" value="hello"></p> </form> </body> </html>
def greet_with_form_data(request): given_name = request.GET["given_name"] family_Name = request.GET["family_name"] return HttpResponse('Hello, {given_name} {family_name}'.format(given_name=given_name, family_name=family_name))
- URLのキャプチャ
- 正規表現を使ったURLのマッピングはDjangoのすばらしい設計の一つ。 Djangoは正規表現のパターンキャプチャ機能を使ってマッチしたURLから 値を取り出す仕組みを提供しているため。
def reverse_url_bit(request, bit=''): """Displays reversed url bit, which is captured in urlconf. """ return HttpResponse(revesed(bit), content_type="text/plain") # views.py def url_sum(request, a, b): a_int = int(a) b_int = int(b) return HttpResponse(str(a_int+b_int), content_type="text/plain") # urls.py url(r'^sum/(\d+)/(\d+)/$', url_sum),
テンプレートを使う
def showmetadata(request): template = Template(str) context = Context() context.update({'metadata': request.META}) template.render(context)
- テンプレート作成の流れ
- テンプレートの作成
- コンテキストオブジェクトの作成
- コンテキストオブジェクトの更新
- テンプレートへのコンテキストオブジェクトのレンダリング