"BOKU"のITな日常

62歳・文系システムエンジニアの”BOKU”は日々勉強を楽しんでます

簡単な入力画面を作成/Formの利用&CSRF対策を追加/Django3.0+Bootstrap4

今回は簡単な入力画面を作って以下をやります。

  • テキストボックスなどのタイトルラベルを任意の名前にする
  • 送信ボタンを押してPOSTで画面遷移する時のCSRF検証エラーの回避 

django2.0・3.0で動作確認済です。

f:id:arakan_no_boku:20190320212948j:plain

 

簡単な入力画面を作ってみます。

 

HTMLファイルの作成

 

以下のようなHTMLファイルを作ります。

hello.html 

{% load static %}
<!doctype html>
<html lang="ja">
    <head>
         <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> 
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">    
  </head>
    <body>
        <div class="container">
            <div class="row text-center">
                <h1>Hello Form!!</h1>
            </div>
            <div class="row text-center">
                <img src="{% static "images/boku.jpg" %}" />
            </div>
            <div class="row text-center">
                <form action="" method="post">
                    {% csrf_token %}
                    {% if name %}
                        <h1>{{ name }}</h1>
                    {% else %} 
                        {{form.as_p}}
                        </div>
                        <div class="row">
                            <input type="submit" value="送信">
                        </div>
                    {% endif %} 
                </form>
            <div>
        </div>
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    </body> 
</html>

CSSはbotstrap4を使います。

以下に掲載されているテンプレートをコピーしています。

getbootstrap.jp

 

 テキストボックスのフォームを作る

 

入力画面にはdjangoのビルトインの Field クラスを使います。 

docs.djangoproject.com

今回はテキストボックスを一つだけ作るので、「CharField」を使います。 

フォーム表示するソースを作成します。

今回は、hello.pyというファイルにしました。

from django.template.context_processors import csrf
from django.shortcuts import render
from . import helloforms as forms


def hello(request):
    if request.method == 'POST':
        c = {
            'name': request.POST["name"]
        }
    else:
        f = forms.HelloForm(label_suffix=':')
        c = {'form': f}
    c.update(csrf(request))
    return render(request, 'hello.html', c)

 

ポイントを補足します。

以下をインポートしています。

from django.template.context_processors import csrf

そして、requestを以下のようにラップしています。

c.update(csrf(request))

これがCSRF対策です。

このCSRF対策をしないで送信ボタンを押すと、こんなエラー画面がでます。

f:id:arakan_no_boku:20180202090621j:plain

あとは、「request.method == 'POST'」(つまり、送信ボタンが押されてPOSTで遷移してきた状態)か否(初期表示状態)かで、表示を切り替えているくらいで、特に凝ったことはしてません。

なお、上記の対応で、Django1.xxのサンプルだと、インポートパスが「from django.core.context_processors import csrf」って書いてありますが、バージョン2から変わっているみたいです。

urls.pyは「hello.html」なので、こんな感じです。。

from django.contrib import admin
from django.urls import path
from . import views, hello

urlpatterns = [
    path('hello/', hello.hello, name='hello'),
]

  

実行確認です

 

サーバーを動かして。

python hello/manage.py runserver

 

やってみます。

f:id:arakan_no_boku:20191214185116p:plain

 

ためしに「BOKUのITな日常」と入力して、送信ボタンを押します。

f:id:arakan_no_boku:20191214185207p:plain 

OKですね。