[Python]とにかくわかりやすく！Djangoでアプリ開発！ーその３ー

#前回の記事
前回の記事→[とにかくわかりやすく！Djangoでアプリ開発！ーその2ー](https://qiita.com/hiroyuki_mrp/items/18c790034afe83541160)

#本記事の目的
python初心者の方が、本記事を見たあとに、一人でアプリ開発できることを目的にしております。
※インストールや開発環境については記載しません

#環境
macOSX　Sierra
python3.7
django 2.1.5

#前回まで

プロジェクトを立ち上げ(startproject)
→アプリの作成(startapp)
→view.pyを変更してレスポンスを書く
→urls.pyを修正する
→アプリの登録する
→index.html作る
→views.pyを直す
→htmlに変数入れる
→views.pyを直す
→複数ページ作るためにリンクつける
→views.pyを直す
→cssで装飾できるようにする

とここまででした。

ここからはアプリらしくフォームを作成していきます。

#フォームを作る

目に見える画面に用意するものなので、templatesのindex.htmlを修正します。
前回同様にformというURLへの書き出しを行います。このformは後ほどurlpatternsに追加します。
またCSRF対策タグもつけておきました。これでフォーム送信時に、このトークンも一緒に受け渡されて、チェックが行われるので安心です。
※一旦不要なsecondは消します。

```html:index.html
{% load static %}
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>{{title}}</title>
        <link rel="stylesheet" type="text/css"
        href="{% static 'app1/css/style.css' %}"/>
    </head>
    <body>
        <h1>{{title}}</h1>　　　
        <p>{{msg}}</p>
        <form action= "{% url 'form' %}" method = "post"> <!--ここのフォーム使うとformのURLに飛びます-->    
            {% csrf_token %} <!--CSRF対策-->    
            <label for = "msg">ここに入力：</label> <!--入力項目ラベル-->    
            <input id = "msg" type="text" name ="msg"> <!--入力フォーム-->    
            <input type="submit" value="入力"> <!--ボタン-->    
        </form>
    </body>
</html>
```

htmlを変えたので,それを制御するviews.pyの変更も行います。
form関数を作ります。htmlのinputの部分に書いてある通り、ここで送信されたmsgと名付けられたtextを受け取るために、POSTメソッドを利用し送信された値を取り出します。
※一旦不要なsecondは消します。

```python:views.py
from django.shortcuts import render
from django.http import HttpResponse

def aisatsu(request):
    params = {
        'title':'Hello World',
        'msg':'名前を入力してください',
    }
    return render(request,'app1/index.html', params)


def form(request):
    msg = request.POST['msg']
    params = {
        'title':'Hello World',
        'msg':'hello '+msg+'!',
    }
    return render(request,'app1/index.html', params)
```

新しい関数を定義したので、最後にこの関数を呼び出せるように、URLを準備します。urls.pyに追加を行います。　ここに追加することでhtmlのタグをつけるようになります。

```python:urls.py
from django.urls import path
from . import views

urlpatterns = [
    path("",　views.aisatsu,　name=　"aisatsu"),
    path("form",views.form,　name="form"),
]
```

それでは`http://127.0.0.1:8000/app1/`にアクセスして確認します。
※runserverしておいてください。キャッシュによって変更されない可能性があるので、その時はサーバーを止めてから、再度起動してください

以下のようにフォームができています。
<img width="395" alt="スクリーンショット 2019-02-03 20.01.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/241505/9e4fd03f-0e88-4953-e06a-67f594ce915d.png">
入力して、送信！画面が以下のようになればOK！
<img width="411" alt="スクリーンショット 2019-02-03 20.01.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/241505/ee10ff60-fa30-1526-e06d-eb888daea6e5.png">

#今後のために

実はこの使い方は、せっかく入力された名前がクリアになってしまうので、DB登録とのチェック機能やできないなどあまり汎用性がありません。なのでdjangoに用意されているFormクラスを使います。※最初からそれを記載してもよかったのですが...念のため...

ということでまずはapp1フォルダ配下にforms.pyを作成し、以下のようにします。
書いてあるまんまですが、テキスト(char)と整数(int)の入力フィールドを用意して、labelで名前をつけました。大文字小文字に気をつけてください。


```python:app1/forms.py
from django import forms

class Aisatsuform(forms.Form):
    name = forms.CharField(label="name")
    area = forms.CharField(label="area")
    age = forms.IntegerField(label="age")
```
このフォームを利用できるような制御にするために、views.pyを修正していきます。
パラメタの中に、formを作ってインスタンスを入れています。
下の部分では、request.methodで、リクエストがPOSTかどうかチェックをして、そうだったらPOST用の処理を実施しします。GETならば、ページだけ返します。
※POSTとかGET:HTTPメソッド。フォームを使うならPOSTを利用します。他にもいくつかメソッドがありますが、メソッドを見れば、どんなことが行われているかわかるようになっています。
*波括弧の閉じる位置とreturnのインデントに注意

```python:views.py
from django.shortcuts import render
from django.http import HttpResponse
from .forms import AisatsuForm

def aisatsu(request):
    params = {
        'title':'Hello World',
        'msg':'ちゃんと挨拶したいので情報の登録をしてください',
        'form': AisatsuForm(),
    }
    if (request.method=='POST'):
        params['msg'] = 'こんにちは!'+request.POST['name']+'さん!<br>'+request.POST['area']+'にお住まいで<br>年齢は'+request.POST['age']+'歳なんですね!<br>よろしくお願いします。'
        params['form']= AisatsuForm(request.POST)
    return render(request,'app1/index.html', params)
```
少し複雑ですね。冒頭でaisatsuformのインスタンスをformに代入し、もしPOSTリクエストだったら、もう一回POSTの内容でインスタンスを作って上書きを行なっています。同様にmsgも書き換えを行い、POSTされた情報を表示させるようにしています。ここでは\<br>などのhtmlタグが埋め込まれているので、index.htmlで表示させる時に、そうなっていることを知らせなくてはなりません。下記で記述します。

それでは、画面表示直していきます。index.htmlを修正します。
先ほど作ったフォームは丸ごと置き換えます。
{{form}}のところをテーブル(as_table)にしたり、リスト(as_ul)にすることもできます。何も指定しないと横一列にフィールドが設置されます。※tableにする場合は<table>タグが必要です。

```html:index.html
{% load static %}
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>{{title}}</title>
        <link rel="stylesheet" type="text/css"
        href="{% static 'app1/css/style.css' %}"/>
    </head>
    <body>
        <h1>{{title}}</h1>　　　
        <p>{{msg|safe}}</p><!--ここでviews.pyのhtmlを有効化--> 
        <form action= "{% url 'aisatsu' %}" method = "post"> 
            {% csrf_token %} 
            {{form.as_ul}} <!--ここ-->    
            <input type="submit" value="入力"> 
        </form>
    </body>
</html>
```
views.pyを変えている(form関数がなくした)のでurlも元のものに直します。


```python:urls.py
from django.urls import path
from . import views

urlpatterns = [
    path("",views.aisatsu,name="aisatsu"),
]
```



ここまできたら、http://127.0.0.1:8000/app1/
にアクセスしてみます。すごい怪しい感じになりました。

<img width="660" alt="スクリーンショット 2019-02-03 21.28.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/241505/cf4085c9-b2fd-7093-c889-bae092c5c952.png">

情報を送信してみるとこんな感じ

<img width="435" alt="スクリーンショット 2019-02-03 21.28.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/241505/bc967de6-884c-18ff-be06-81d81f882ee0.png">

#この記事はここまで

続きはこちら→[[Python]とにかくわかりやすく！Djangoでアプリ開発！ーその4ー](https://qiita.com/hiroyuki_mrp/items/8aa59ede3b31fd8dddb8)