41
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Django#3(フォームの値を受け取る)

Posted at

Django#3(フォームの値を受け取る)

内容

  • テンプレートにフォームを設置する。
  • POSTリクエストを受け取る
  • リクエストの変数と値の取り出し
  • レスポンスを返す(正常)

下準備

下記の内容でhelloを設定している事。

Django#1(初期設定とhello) - Qiita

URL.py

設定に変更なし。GETもPOSTも同じ設定で受け取れる。

テンプレートにフォームを記述する。

テンプレートファイルを下記の通りに修正する。

template/hello.html
<html>
<body>
  <form action="/hello" method="post">
    {% csrf_token %}
    <div>
      <label for="name">名前</label>
      <input type="text" id="name" name="name">
    </div>
    <div>
      <label for="email">メールアドレス</label>
      <input type="mail" id="email" name="email">
    </div>
    <div>
      <label for="message">内容</label>
      <textarea id="message" name="message">{{ message }}</textarea>
    </div>
    <input type="submit" value="送信する">
  </form>
</body>
</html>

説明。

  • {% csrf_token %}タグについて
    • POSTメソッドはCSRF対策としてトークンで照合を行っている。
    • そのトークンを設定するのがこのタグ。formタグ内に書く。処理は自動的に行われる。
    • これが無いと不正アクセスとしてエラーが発生する。
    • formが複数ある場合は、各formにそれぞれ書く。
  • その他のフォーム部分は普通のHTMLで書ける。
    • DBと紐づけて半自動で生成することも可能。今回はやらない。

views.pyにPOSTリクエストを受け取る処理を追記する。

views.pyのHelloViewにpostメソッドを追記する。

views.py
class HelloView(View):
    def get(self, request, *args, **kwargs):
        context = {
            'message': "Hello World! from View!!",
        }
        return render(request, 'hello.html', context)

    def post(self, request, *args, **kwargs):
        context = {
            'message': "POST method OK!!",
        }
        return render(request, 'hello.html', context)

hello = HelloView.as_view()

説明

  • getメソッド
    • 特に変更なし。
  • postメソッド
    • まるっと追加。内容はgetとほぼ同一。区別できるようにメッセージだけ変更。
  • 動作としては、HTTPリクエストのリクエストメソッドに応じて
    ビュークラス内のgetメソッドかpostメソッドが実行される。
    • なので、全く別の処理にしてもOK、同一の動作ならまとめるのもOK。今回はべた書き。
    • pushとかdeleteへの挙動は不明。ブラウザ自身がgetとしてリクエストしてしまうので。

動作確認

この時点で、http://IPアドレス:8000/helloにアクセスすると下記のような画面が表示される。

Clipboard01.jpg

ボタンをクリックすると下記のような画面が表示される。

Clipboard02.jpg

テキストボックスのメッセージがこの画面のように表示されていたら、POST用の処理が正しく呼び出されている。
まだ、フォームに入力した文字は保持されない。その処理は以下。

HTTPリクエストからフォームの入力値を取り出す

次に、POSTリクエストからフォームの入力値を受け取る方法。
HTTPリクエストに付随する情報はビュークラスのget, postメソッドの2番目の引数に入ってくる。
具体的には下記のrequest

    def post(self, request, *args, **kwargs):

このrequestの詳細は下記ドキュメントを参照。ここではとりあえずフォームの入力値だけ取り出す。

リクエストとレスポンスのオブジェクト | Django ドキュメント | Django

値の取得はrequest.POST['フォームのID']でOK。
このうち、request.POSTがDjangoのQueryDictという型で、Pythonの辞書型の拡張になっている。
フォームの入力値は普通に辞書型のようにアクセスできる。

QueryDict型の詳細は下記を参照。

QueryDict

レスポンスを返す

フォームの入力値にアクセスする手段が分かったので、ビュー関数とテンプレートを修正して、
入力値をそのまま埋め込んで返す処理を書く。

まずビュー関数の修正。request.POSTの値をそのままname, email, messageの各変数に設定している。

views.py
    def post(self, request, *args, **kwargs):
        context = {
            'name': request.POST['name'],
            'email': request.POST['email'],
            'message': request.POST['message'],
        }
        return render(request, 'hello.html', context)

次いでテンプレートの修正。差分のみ記載。valueを付け加えた。

7c7
<       <input type="text" id="name" name="name" value="{{ name }}">
---
>       <input type="text" id="name" name="name">
11c11
<       <input type="mail" id="email" name="email" value="{{ email }}">
---
>       <input type="mail" id="email" name="email">

動作確認。http://IPアドレス:8000/helloにアクセスして、フォームに何か入力して、
ボタンをクリックして、入力した文字がそのまま残っていたらOK

Clipboard03.jpg

入力値のチェックやDBと連携して保存したりとかの処理はまた別途。

41
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?