簡易ログインアプリケーションの説明(Template版)

5.3 簡易ログインアプリケーションの説明(Template版)

5.3で作成したアプリケーションをもとに、Templateを利用する処理が実際どのような流れで動作しているのかを説明していきます。

5.3.1 urls.py

第4章でも説明した通り、「urls.py」は、クライアントがアクセスしたURLと関数を関連付ける機能があります。DjangoではURLにアクセスすると親プロジェクト(「django_basic」ディレクトリ)直下の、「urls.py」を読み込み、「urlpattern」内の要素から該当するURLを探します。

■ソースコード
【ファイル名:django_basic/urls.py】

「urlpattern」内を確認すると、8行目から「path(‘loginform/’, include(‘LoginForm.urls’))」と記載されているので、「http://localhost:8000/loginform/●●●」にアクセスした場合、「include(‘LoginForm.urls’))」が読み込まれるということがわかります。

このinclude関数は、2行目でimportしたものです。

この関数は指定した引数のモジュールを読み込む関数ですので、「include(‘LoginForm.urls’))」が実行されることで「LoginForm」ディレクトリ直下の「urls.py」が読み込まれます。
つまりは「http://localhost:8000/loginform/●●●」にアクセスした場合、「LoginForm」ディレクトリ直下の「urls.py」に処理が引き継がれるということです。

図 5.3 1:urls.pyの処理内容

では引き継いだ先の「LoginForm」ディレクトリ化の「urls.py」ではどのような処理が行われているのでしょうか?

【ファイル名:LoginForm/urls.py】

    from django.urls import path
    from . import views

    urlpatterns = [
        path('form/', views.form),
        path('success/', views.success,name="success"),
    ]
	

まず2行目で「from . import views」が実行されています。「from .」の「.(ピリオド)」はカレントディレクトリ(現在のディレクトリ)を意味します。
「LoginForm」ディレクトリ内で実行されているファイルなので、「LoginForm」内の「views.py」がimportされるということです。

    from . import views
	

こちらも「urls.py」ファイルですので、特定のURLにアクセスした場合、「urlpatterns」内で合致する処理が実行されますが、先ほどの「django_basic/urls.py」では「http://localhost:8000/loginform/」にアクセスした場合の処理として「LoginForm/urls.py」が読み込まれています。
そのため「LoginForm/urls.py」内の処理では、「http://localhost:8000/loginform/」を基準(カレントディレクトリ)に、「…/loginform/」以下の階層を「urlpatterns」内から探します。
つまりは「http://localhost:8000/loginform/●●●」における「●●●」を探すということです。

では「LoginForm/urls.py」内のurlpattern内ではどのような処理がなされているのでしょうか。5、6行目に次のように記載されています。

    path('form/', views.form),
    path('success/', views.success,name="success"),
	

5行目の「path(‘form/’, views.form),」の「’form/’」は、「http://localhost:8000/loginform/form」と同じです。また「views.form」の「views」は「LoginForm」内の「views.py」ですので、「views.form」は、「LoginForm/views.py」の「form関数」ということになります。

つまりは「http://localhost:8000/loginform/form」にアクセスすると「LoginForm/views.py」の「form関数」が読み込まれるということです。

以上を踏まえると6行目の「path(‘success/’, views.success, name=”success”)」により、「http://localhost:8000/loginform/success」にアクセスすると「LoginForm/views.py」の「success関数」が読み込まれるということもわかります。

また6行目の「name=”success”」は、Template(form.htmlやsuccess.htmlなど)内でURLを指定する際に使用するためのものです。
「http://localhost:8000/loginform/success」を絶対パスで指定するのではなく、簡略化した形式で指定することができます。
詳しくは「form.html」の解説の際に再度、説明します。

図 5.3 2:urls.pyの処理内容

5.3.2 View(views.py)①:form関数

DjangoではURLにアクセスすると「urls.py」が読み込まれた後、「views.py」内の関数が読み込まれます。続いて「views.py」内の処理を確認しましょう。

【ファイル名:LoginForm/views.py】

    from django.shortcuts import render

    def form(request):
        #画面に出力するtemplateを指定し、templateを表示させる
        return render(request,'form.html')

    def success(request):

        #templateに渡す変数を用意
        userId = request.POST["id"]
        password = request.POST["pass"]

        params = {
            'id':userId,
            'pass':password,
            }
        #画面に出力するtemplateを指定し、templateを表示させる
        return render(request, 'success.html',params)
	

3~5行目では「form関数」が記載されています。
5行目の「return render(request,’form.html’)」における、render関数はTemplateをレンダリングするための関数です。

    def form(request):
        #画面に出力するtemplateを指定し、templateを表示させる
        return render(request,'form.html')
	

レンダリングとは、ある抽象的なデータを元に画像や映像、音声などの形に整理するための操作です。
ここでのレンダリングは、テンプレートファイル(form.hmtl)内の情報を、webページとして整理するためのものだと思ってください。
render関数では第一引数にrequest(クライアント側の情報をまとめたHttpRequestクラスのインスタンス)、第二引数に「テンプレートファイル」を指定します。
「return render(request,’form.html’)」では「form.html」を第二引数に指定しているので、form関数を実行することで「form.html」の内容がWebページとして表示されます。

図 5.3 3:form関数の実行結果

先ほどの内容を踏まえると、form関数は「http://localhost:8000/loginform/form」にアクセスした際に、実行される関数ですので、「http://localhost:8000/loginform/form」にアクセスすると「form.html」がWebページとして表示されるということです。
「http://localhost:8000/loginform/form」にアクセスした場合の処理全体の流れをまとめると以下の図のようになります。

図 5.3 4:処理全体の流れ

5.3.3 Template①:form.html

「form関数」を通じて「http://localhost:8000/loginform/form」にアクセスした際の全体の流れを確認しましたが、画面表示(Template)の役割を担う「form.html」の中身を確認しましょう。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Login Form</title>
    </head>
    <body>
        <form action="{% url 'success' %}" method="post">
            {% csrf_token %}
            ID: <input type="text" name="id"><br>
            PASSWORD: <input type="password" name="pass"><br>
            <input type="submit" value="Login">
        </form>
    </body>
    </html>
	

7~12行目ではログインフォームを設けるため「formタグ」が使用されています。
「formタグ」の開始タグではaction属性を介して、送信ボタンが押された場合の遷移先のURLを指定できます。

    <form action="{% url 'success' %}" method="post">
        {% csrf_token %}
        ID: <input type="text" name="id"><br>
        PASSWORD: <input type="password" name="pass"><br>
        <input type="submit" value="Login">
    </form>
	

7行目を確認すると「<form action=”{% url ‘success’ %}” method=”post”>」となっており、action属性に「{% url ‘success’ %}」が指定されています。
「{% url ‘success‘ %}」は「urls.py」で指定したURLを利用するためのものです。

【ファイル名:LoginForm/urls.py】

    from django.urls import path
    from . import views

    urlpatterns = [
        path('form/', views.form),
        path('success/', views.success,name="success"),
    ]
	

「LoginForm/urls.py」の6行目を確認すると、「success/」に対して「name=”success”」が指定されています。

「urlpatterns」の各要素内でname属性に指定した値(success)を用いることで、テンプレートファイル(htmlファイル)内で対応するurl(success/)を指定できる仕組みとなっています。
具体的には「{% url ‘name属性に指定された値’ %}」と記載することで、対応するurlの絶対パスが利用できます。
つまり「{% url ‘success‘ %}」と指定することで「http://localhost:8000/loginform/success」を利用できるということであり、送信(login)ボタンを押すと「http://localhost:8000/loginform/success」に遷移されるということです。

図 5.3 5:{% url ‘success’ %}の仕組み

8行目で記載されている「{% csrf_token %}」は、Djangoでデフォルトに用意されているCSRFの検証機能を実施するためのものです。

    {% csrf_token %}
	

CSRF(クロスサイトリクエストフォージェリ)とは、Webアプリケーションにおける脆弱性を利用した攻撃方法を指します。
パスワードなどログイン情報を扱うPOSTメソッドのフォームを用いる場合、DjangoではCSRF対策として「{% csrf_token %}」を用いるのが一般的です。
また「{% csrf_token %}」は、<form>の開始タグの後に記載します。

ここまでの処理の流れをまとめると以下の図の通りになります。

図 5.3 6:処理全体の流れ

5.3.4 View(views.py)②:success関数

「http://localhost:8000/loginform/form」のWebページ内で「login」ボタンをクリックすると、「http://localhost:8000 /loginform /success」に遷移します。
先ほど説明した通り、「http://localhost:8000 /loginform /success」にアクセスすると「success関数」が実行されますので、以下、「success関数」の処理の流れを確認していきます。

【ファイル名:views..py】

    def success(request):

        #templateに渡す変数を用意
        userId = request.POST["id"]
        password = request.POST["pass"]

        params = {
            'id':userId,
            'pass':password,
            }
        #画面に出力するtemplateを指定し、templateを表示させる
        return render(request, 'success.html',params)
	

10、11行目で使用されている「request.POSTメソッド」は、POST送信の値を取得するためのものです。

    userId = request.POST["id"]
    password = request.POST["pass"]
	

送信元である「http://localhost:8000/loginform /form」のフォーム内で入力した値が、フォーム内のname属性の値に紐づいて、10、11行目で宣言されている変数userId、passwordに格納されます。

変数userIdで使用されるPOSTメソッドの引数には”id”が指定されている一方で、「form.html」を確認すると9行目のinputタグでname属性の値が”id”となっているので、このinputタグで入力した値がuserIdに格納されます。

【ファイル名:form.html】送信元の記述

	ID: <input type="text" name="id"><br>
	

【ファイル名:form.html】送信先の記述

	userId = request.POST["id"]
	

変数passwordも同様に、form.htmlの10行目の「<input type=”password” name=”pass”>」で入力した値が格納されます。

図 5.3 7:処理全体の流れ

続いて13~16行目では、paramsという辞書型の変数を宣言しています。それぞれキー「’id’」に対応する値として変数userId、「’pass’」に対して変数passwordを指定します。

    params = {
       'id':userId,
       'pass':password,
       }
	

18行目ではrender関数の第二引数に「’success.html’」が指定されているので、「success関数」が実行されると「success.html」がWebページとして表示されることがわかります。

    return render(request, 'success.html',params)
	

またrender関数の第三引数には変数paramsが指定されています。これは表示させるTemplate(success.html)に値を引き渡す際に使用するためのもので、辞書型の変数を指定します。
引数に指定した値がそのままTemplateに引き継がれます。詳しくは「success.html」の解説時に再度、後述します。

5.3.5 Template②:success.html

以上のことから「http://localhost:8000/loginform/success」にアクセスすると「success関数」が実行され、「success.html」がWebページとして表示されることがわかりました。
最後に「success.html」の内容を確認していきましょう。

【ファイル名:success.html】

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>ログイン結果</title>
    </head>
    <body>
        ログイン情報<br>
        <span>{{id}}</span>
        <span>{{pass}}</span>
    </body>
    </html>
	

9、10行目で「{{id}}」、「{{pass}}」と記載されていますが、ここではView(success関数)から渡された値を取得しています。

「success関数」の内容を振り返ると、「params」という辞書型の変数をTemplate(success.html)に引き渡しました。
【ファイル名:views.py】

    return render(request, 'success.html',params)
	

辞書型の変数には複数の値を格納することができ、Templateで各値を取得する際には、その値に対応するキーを使い、{{キー名}}と指定することで取得します。

【ファイル名:views.py】

    params = {
       'id':userId,
       'pass':password,
       }
	

キー「’id’」に該当する値は変数userIdなので、「{{id}}」と指定すると変数userIdの中身(実行結果ではadmin)が表示され、キー「’pass’」に該当する値は変数passwordなので、「{{pass}}」と指定すると変数userIdの中身(実行結果ではpassword)が表示されます。

図 5.3 8:処理全体の流れ

このようにViewで宣言した変数や値をTemplateで用いることができますが、メソッドや属性を持つインスタンスを値、変数としてTemplateに渡すこともできます。


NEXT>> 5.4 ViewからTemplateへの値の引き渡しについて