nikkie-ftnextの日記

イベントレポートや読書メモを発信

PyCon mini 静岡 Django入門トーク 補足資料 | Djangoが覆うWebアプリの世界 #pycon_shizu

はじめに

頑張れば、何かがあるって、信じてる。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つがあります。

HTTP通信では、クライアントとサーバ間で以下のやり取りをします。

  • クライアントはサーバにHTTPリクエスを送信(Webブラウザに入力したデータも含みます)
  • サーバはHTTPリクエストに応じた処理をしてHTTPレスポンスを返却
  • クライアントはHTTPレスポンスに含まれるHTMLを解釈して表示

f:id:nikkie-ftnext:20200229003809p:plain

それでは、Djangoが覆うHTTP通信について、以下で見ていきましょう。
アプリケーションの4要素(URL設定、ビュー、テンプレート、モデル)がHTTPリクエストやレスポンスとどう関わるかについて見ていきます。

URL設定

URL設定はHTTPリクエストと関係します。
HTTPリクエストにはURIという項目があるのですが、URL設定はURIを処理します。

HTTPリクエストの一部

GET http://example.com/ HTTP/1.1
(以下略)

URIhttp://example.com/の部分です。

URL設定はHTTPリクエス4URIを見ます。
そして、URIのパスと一致するビューを呼び出します5

explain-how-django-works-for-beginner/urls.py at 8f1eaa0856cbfb499d05fdcdb2adb4fb997665ea · ftnext/explain-how-django-works-for-beginner · GitHub

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/ 以外の場合は
    # 設定していないのでエラー
]

f:id:nikkie-ftnext:20200229005542p:plain

ビュー

ビューは、HTTPリクエストともHTTPレスポンスとも関係します。
ビューはHTTPリクエストの情報を使って処理をします。
そして、処理の結果をHTTPレスポンスとして返します。

ビューが処理に使うHTTPリクエストの情報としては、例えば、HTTPメソッドがあります。

(再掲)HTTPリクエストの一部

GET http://example.com/ HTTP/1.1
(以下略)

HTTPメソッドはGETの部分です6

HTTPレスポンスには2つのポイントがあります。

ステータスコードはHTTPの通信結果を表します(処理が正常に行われたら200のように決まっています)。
メッセージボディはクライアントのWebブラウザに表示される部分です。

ビューが処理の結果をレスポンスとして返すことを実現する最も単純な方法はHttpResponseを返すことです。

explain-how-django-works-for-beginner/views.py at 8f1eaa0856cbfb499d05fdcdb2adb4fb997665ea · ftnext/explain-how-django-works-for-beginner · GitHub

def post_list(request):
    # 引数requestはHttpRequest(Django流のHTTPリクエストの扱い方)
    # request.methodでHTTPメソッドを確認できる
    if request.method == 'GET':
        # メッセージボディを指定して,HttpResponseを返す(→ブラウザに表示される)
        return HttpResponse('GETリクエストへのレスポンスです')
    # 以下略

f:id:nikkie-ftnext:20200229005608p:plain

このようにして、URL設定とビューがあればHTTPに則ってリクエストにレスポンスを返すことができます7

テンプレート

URL設定とビューで返すHTTPレスポンスは単なる文字列でHTMLではありませんでした。
HTTPレスポンスとしてHTMLを使うにはテンプレートの出番です。
HTTPレスポンスのメッセージボディにHTMLを文字列として含めます

explain-how-django-works-for-beginner/views.py at 1db8d0827afac7514725db489fc21efcf82bf25d · ftnext/explain-how-django-works-for-beginner · GitHub

def post_list(request):
    # 指定したテンプレート(HTML)をメッセージ本文に入れた
    # HTTPレスポンス(HttpResponse)を、render関数で作って返す
    return render(request, 'blog/post_list.html', {})
    # (データを埋め込まない場合)URL設定に対してテンプレートが対応する形になる

以下のように連携します。

  1. URL設定がパスに対応するビューを呼び出し
  2. ビューが処理
  3. ビューがテンプレートを取得し、処理結果を埋め込んでHTTPレスポンスとして返す

f:id:nikkie-ftnext:20200229011004p:plain

render関数の動きを理解するには、Django公式ドキュメントの投票アプリチュートリアルがオススメです。
render関数がHttpResponseを返していることが分かります。

モデル

テンプレートを使うことでパスに対して決まったHTMLをHTTPレスポンスとして返せるようになりました8
次はデータをテンプレートから切り出して考えます。
データをデータベースで管理し、リクエストに応じてデータを取り出します。
取り出したデータをテンプレートの中に埋め込んでHTTPレスポンスを作成します。
また、HTTPリクエストの情報をもとにデータを保存することも可能です。

データベースからデータの取得・保存に使うのが、モデルです。

実装は、モデルを使って取得したデータを辞書でrenderの第3引数に渡します(仕組みは、テンプレートのところで紹介した投票アプリチュートリアルをどうぞ!)。

explain-how-django-works-for-beginner/views.py at 3b0133546c8a8a565de5a0427f164b666b5378e0 · ftnext/explain-how-django-works-for-beginner · GitHub

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})

以下のように連携します。

  1. URL設定がパスに対応するビューを呼び出し
  2. ビューが処理(モデルを使ってデータの取得や保存をする
  3. ビューがテンプレートを取得し、処理結果を埋め込んでHTTPレスポンスとして返す

f:id:nikkie-ftnext:20200229011031p:plain

まとめ

Webアプリを支えるHTTPリクエストとHTTPレスポンスという観点から、Djangoが覆っている部分に光を当ててみました。
Django Girls Tutorialを何周かしてDjangoに慣れてきたら、「Webアプリとは何か」を学んでみると視野が広がるのではないでしょうか。

Djangoを使っていくとDjangoの使い方を覚えるような状況にもなります。
ですが、Djangoの使い方を覚えるだけで済むというのは、DjangoがHTTP通信を覆っていて、開発者がHTTPリクエストやHTTPレスポンスを直接扱わなくても済むから可能になっているのだと気づきました。
また、HTTP通信は共通化しやすいと思うので、Djangoが覆っているのも納得です。

最後に今回Webアプリについて学ぶ際に参考になった書籍を紹介します。

10年ほど前の本ですが、HTTP通信の説明は現在でも通用する(Webの大元は10年前から変わっていない)と思いました。

補足資料は以上です。


  1. PyCon mini 静岡のテーマ「あなたの知らないPython」になぞらえています

  2. この視点は登壇者練習会で岡崎さんからいただきました。ありがとうございます

  3. 裏のcmath複素数を扱うライブラリ)トークをどうぞ!PyCon mini Shizuoka - 君はcmathを知っているか

  4. 前提として、Djangoで作られたWebアプリが受け取ったHTTPリクエストはDjango流のオブジェクトに変換されています。

  5. ビューにはHTTPリクエストを表すオブジェクトが渡されます

  6. 今回は詳細には立ち入りませんが、URIへのデータの送信の仕方を表すもので、GETの他にPOSTなど何種類かあります

  7. このことを登壇ではURLとビューで最小限のWebアプリが作れると表現しています

  8. パスpost/1/には1.htmlを、post/2/には2.htmlを返すというのは一案ですが、post/10/まで用意するだけでも大変です。そこで、post/整数/に対してtemplate.htmlを返すようにし、中身のデータを1番のデータ、2番のデータ、、、というようにWebアプリとは別で管理します(→データベース)。