はじめに
頑張れば、何かがあるって、信じてる。nikkieです。
2020/02/29にPyCon mini 静岡でDjango入門トークをします。
発表準備した事項のうち、資料に盛り込みきれなかった部分を補足資料としてこの記事にまとめます。
目次
補足資料:Djangoが覆うWebアプリの世界 に至るまで
登壇準備をするに当たり、Django Girls Tutorialの内容について、Workshopなどでしている自分の説明を見直すとともに、「そもそもWebアプリとは何か」を説明できるようにインプットしました。
その中で、Webアプリの肝はHTTPで、DjangoがHTTPを覆っているから早く開発できるという理解に至りました。
「これは言ってみれば、DjangoでWebアプリを始めたあなたの知らないWebアプリの世界1だなあ」と思い、Webアプリについても登壇で言及しようとしました。
ですが、Django入門について話すだけでも30分はギリギリというフィードバック2をいただき、"あなたの知らないWebアプリの世界"はスライドから切り出すことを決めました。
誰のための補足資料?
PyCon mini 静岡のトークは、Web開発に興味がある方に、Djangoを紹介し、チュートリアルの見取り図を提供するものとなっています。
ですので、Djangoのチュートリアルを終えている方や個人のアプリ開発で使い出している方にとっては、申し上げにくいのですが、今回のトークに新しい発見はあまりないと思います3。
そのような方に伝えたい内容が、泣く泣くトークから切り出した"あなたの知らないWebアプリの世界"(=この補足資料)です。
Djangoのチュートリアルを一度終えている方、Djangoの中身についてチュートリアルよりも詳しく知りたいという方は、ぜひ続きを読んでみてください。
それでは以下でDjangoが覆うWebアプリの世界を見ていきましょう。
リクエストとレスポンス
Webアプリは、Webという仕組みを使ったアプリケーションです。
インターネットに接続されたコンピュータ間での情報共有を実現するのがWebです(HTMLを使います)。
Webでコンピュータ同士が通信する際に、HTTPという取り決めに則ります。
HTTPに則った通信の登場人物には以下の2つがあります。
- クライアント(Webブラウザ。Google ChromeやFirefoxなど)
- サーバ(Webアプリが動くコンピュータ)
HTTP通信では、クライアントとサーバ間で以下のやり取りをします。
- クライアントはサーバにHTTPリクエストを送信(Webブラウザに入力したデータも含みます)
- サーバはHTTPリクエストに応じた処理をしてHTTPレスポンスを返却
- クライアントはHTTPレスポンスに含まれるHTMLを解釈して表示
それでは、Djangoが覆うHTTP通信について、以下で見ていきましょう。
アプリケーションの4要素(URL設定、ビュー、テンプレート、モデル)がHTTPリクエストやレスポンスとどう関わるかについて見ていきます。
URL設定
URL設定はHTTPリクエストと関係します。
HTTPリクエストにはURIという項目があるのですが、URL設定はURIを処理します。
HTTPリクエストの一部
GET http://example.com/ HTTP/1.1 (以下略)
URIはhttp://example.com/
の部分です。
URL設定はHTTPリクエスト4のURIを見ます。
そして、URIのパスと一致するビューを呼び出します5。
urlpatterns = [ # リクエスト中のURIが 127.0.0.1:8000/ のときは、 # パスが''(空文字)となる。 # blog/views.py の post_list 関数を呼び出す path('', views.post_list, name='post_list'), # リクエスト中のURIが 127.0.0.1:8000/ 以外の場合は # 設定していないのでエラー ]
ビュー
ビューは、HTTPリクエストともHTTPレスポンスとも関係します。
ビューはHTTPリクエストの情報を使って処理をします。
そして、処理の結果をHTTPレスポンスとして返します。
ビューが処理に使うHTTPリクエストの情報としては、例えば、HTTPメソッドがあります。
(再掲)HTTPリクエストの一部
GET http://example.com/ HTTP/1.1 (以下略)
HTTPメソッドはGET
の部分です6。
HTTPレスポンスには2つのポイントがあります。
- ステータスコード
- メッセージボディ
ステータスコードはHTTPの通信結果を表します(処理が正常に行われたら200のように決まっています)。
メッセージボディはクライアントのWebブラウザに表示される部分です。
ビューが処理の結果をレスポンスとして返すことを実現する最も単純な方法はHttpResponse
を返すことです。
def post_list(request): # 引数requestはHttpRequest(Django流のHTTPリクエストの扱い方) # request.methodでHTTPメソッドを確認できる if request.method == 'GET': # メッセージボディを指定して,HttpResponseを返す(→ブラウザに表示される) return HttpResponse('GETリクエストへのレスポンスです') # 以下略
このようにして、URL設定とビューがあればHTTPに則ってリクエストにレスポンスを返すことができます7。
テンプレート
URL設定とビューで返すHTTPレスポンスは単なる文字列でHTMLではありませんでした。
HTTPレスポンスとしてHTMLを使うにはテンプレートの出番です。
HTTPレスポンスのメッセージボディにHTMLを文字列として含めます。
def post_list(request): # 指定したテンプレート(HTML)をメッセージ本文に入れた # HTTPレスポンス(HttpResponse)を、render関数で作って返す return render(request, 'blog/post_list.html', {}) # (データを埋め込まない場合)URL設定に対してテンプレートが対応する形になる
以下のように連携します。
- URL設定がパスに対応するビューを呼び出し
- ビューが処理
- ビューがテンプレートを取得し、処理結果を埋め込んでHTTPレスポンスとして返す
render
関数の動きを理解するには、Django公式ドキュメントの投票アプリチュートリアルがオススメです。
render
関数がHttpResponse
を返していることが分かります。
モデル
テンプレートを使うことでパスに対して決まったHTMLをHTTPレスポンスとして返せるようになりました8。
次はデータをテンプレートから切り出して考えます。
データをデータベースで管理し、リクエストに応じてデータを取り出します。
取り出したデータをテンプレートの中に埋め込んでHTTPレスポンスを作成します。
また、HTTPリクエストの情報をもとにデータを保存することも可能です。
データベースからデータの取得・保存に使うのが、モデルです。
実装は、モデルを使って取得したデータを辞書でrender
の第3引数に渡します(仕組みは、テンプレートのところで紹介した投票アプリチュートリアルをどうぞ!)。
def post_list(request): # ブログ投稿のうち、published_date(公開日)が現在より前のものを取得し。 # 公開日の昇順(以前に公開されたものほど上)に並べ替える posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') # 取得した投稿データpostsをテンプレートでpostsという名前で扱えるように渡す return render(request, 'blog/post_list.html', {'posts': posts})
以下のように連携します。
- URL設定がパスに対応するビューを呼び出し
- ビューが処理(モデルを使ってデータの取得や保存をする)
- ビューがテンプレートを取得し、処理結果を埋め込んでHTTPレスポンスとして返す
まとめ
Webアプリを支えるHTTPリクエストとHTTPレスポンスという観点から、Djangoが覆っている部分に光を当ててみました。
Django Girls Tutorialを何周かしてDjangoに慣れてきたら、「Webアプリとは何か」を学んでみると視野が広がるのではないでしょうか。
Djangoを使っていくとDjangoの使い方を覚えるような状況にもなります。
ですが、Djangoの使い方を覚えるだけで済むというのは、DjangoがHTTP通信を覆っていて、開発者がHTTPリクエストやHTTPレスポンスを直接扱わなくても済むから可能になっているのだと気づきました。
また、HTTP通信は共通化しやすいと思うので、Djangoが覆っているのも納得です。
最後に今回Webアプリについて学ぶ際に参考になった書籍を紹介します。
「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか
- 作者:小森 裕介
- 発売日: 2010/04/10
- メディア: 大型本
10年ほど前の本ですが、HTTP通信の説明は現在でも通用する(Webの大元は10年前から変わっていない)と思いました。
補足資料は以上です。
-
この視点は登壇者練習会で岡崎さんからいただきました。ありがとうございます↩
-
裏の
cmath
(複素数を扱うライブラリ)トークをどうぞ!PyCon mini Shizuoka - 君はcmathを知っているか↩ -
前提として、Djangoで作られたWebアプリが受け取ったHTTPリクエストはDjango流のオブジェクトに変換されています。↩
-
このことを登壇ではURLとビューで最小限のWebアプリが作れると表現しています↩
-
パス
post/1/
には1.htmlを、post/2/
には2.htmlを返すというのは一案ですが、post/10/
まで用意するだけでも大変です。そこで、post/整数/
に対してtemplate.htmlを返すようにし、中身のデータを1番のデータ、2番のデータ、、、というようにWebアプリとは別で管理します(→データベース)。↩