mizzsugar’s blog

日々感じていることや学んだことを書きます。エンジニアリング以外にも書くかもしれません。

【Python・Django入門】フォームに入力して送信したら、入力した値が表示される方法

1.プロジェクトを作る Djangoはプロジェクトを作成して、その中にWebアプリケーションを作成します。 プロジェクトを作りたいディレクトリに移動して、以下のコマンドを実行します。

django-admin startproject myProject

次に、myProjectのディレクトリに移動した後、 以下のコマンドでmyProjectというプロジェクトの中に myAppというWebアプリケーションを作成します。

python3 manage.py startapp myApp

次に、myProject/settings.pyのINSTALLED_APPSを編集します。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myApp',
]

models.pyを編集。 入力した値をDBに保存するため。

models.py

from django.db import models

class InputForm(models.Model):
    name = models.CharField()
    age = models.IntegerFiels();
    comment = models.TextField()

コマンドラインにて、以下のコマンドを実行します。

python3 manage.py makemigrations  myApp
python3 manage.py migrate myApp

makemigrationsでmodels.pyで設定したクラスを元にSQLを発行し、 migrat絵でそのSQLを実行し、DBにテーブルを生成します。

DBを確認すると、テーブル生成されていることがわかります。

f:id:mizzsugar:20180625223118p:plain

次に、templateフォルダを配置します。 その中に、htmlファイルを配置します。

入力フォームのhtmlファイルを作成します。

post_new_post.html

<form action="/output" enctype="multipart/form-data" method="POST">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="submit">
</form>

CSRF(ログイン済みの別のWebサイト上で、意図しない何らかの操作を行わせる攻撃手法のこと)対策として、 {% csrf_token %}を入力します。 コンテキスト変数 form を使ってテンプレートに inputForm インス タンスを渡しています。

list.html

<h2>POSTS</h2>


{% for post in posts %}
    <p>{{ post.name }}は{{ post.age }}です</p>
    <p>{{ post.comment }}</p>
    <hr>
{% endfor %}

入力フォームのフィールドを定義する、 forms.pyはmyApp内に作成します。

forms.py

from django import forms
#formsというフォーム処理をするライブラリをインポートします。

class InputForm(forms.Form):
    name = forms.CharField(max_length=30)
    age = forms.IntegerField()
    comment = forms.CharField(widget=forms.Textarea)

クラス内に入力するデータを、フィールドを持って定義します。 名前は文字数が比較的少ないのでCharFieldを用います。 TextFieldを利用すると、「module 'django.forms' has no attribute 'TextField'」というエラーが出力されます。 FormクラスはTextFieldが存在しないクラスだからです。 代わりにCharField(widget=forms.Textarea)を利用します。

views.pyを編集します。

import django.http
import myApp.forms
import myApp.models
from django.shortcuts import render


def post_new_post(request):
    if request.method == 'POST':
        form = myApp.forms.InputForm(request.POST)
        if form.is_valid():
            myApp.models.Post.objects.create(name=request.POST['name'], age=request.POST['age'], comment=request.POST['comment'])
            return django.http.HttpResponseRedirect('/list')
    else:
        form = myApp.forms.InputForm()
    return render(request, 'post_new_post.html', {'form': form})

def list(request):
    posts = myApp.models.Post.objects.all()
    return render(request, 'list.html', {'posts': posts}) 

myApp.models.Post.objects.create(name=request.POST['name'], age=request.POST['age'], comment=request.POST['comment']) こちらで、Postクラスを元に生成されたテーブルにレコードを挿入します。 ()内の引数は、models.pyで登録したクラスのフィールドです。

name=request.POST['name'] の左のnameはmodels.pyのPOSTクラスのフィールドのnameです。 左のnameはforms.pyで登録したフィールド名のnameです。

django.http.HttpResponseRedirect('/output')で、出力先のURLに移動します。 POSTメソッドで、フォームに入力した内容がvalidなら 必ずHttpResponseRedirect(url)にします。

HttpResponseRedirect(url)は、POSTで返って来たデータを安全に破棄して違うviewに遷移させるからです。 render(request,'表示させたいhtmlファイル名',{'html上で利用する変数名':右で定義したhtml上の変数を指す変数}は 単純にページを表示させる時に利用します。

return render(request, 'output.html', {'posts': posts}) の場合、 posts = myApp.models.Post.objects.all() で定義しているpostが{}内の右のpostsになります。

urls.pyに各画面の URLを設定します。

urls.py

urlpatterns = [
    path("list", myApp.views.list),
    path("new_post", myApp.views.post_new_post),
    path('admin/', admin.site.urls),
]

コマンドラインで以下のコマンドを実行すると、コマンドラインにURLが表示されます。 その URLをブラウザで開き、urls.pyで設定したURLに移動しましょう。

python3 manage.py runserver