[Lightsail Django]No12 入力フォームを画面に表示しDB登録する
Djangoでは、forms.py、ModelFormを利用しテーブルの登録値として必要な入力フォームを少ないコードで、画面表示することができます。
また表示されたフォーム情報をPOSTし、DB登録も簡単なコードでできます。
前提
プロジェクト名:TEST
アプリ名:APP_TEST
/opt/bitnami/projects/[プロジェクト名]/[アプリ名]/
/opt/bitnami/projects/TEST/APP_TEST/
1.画面に入力フォームを表示する手順
1-1.models.py(入力フォームの値を最終的にこのテーブルに登録する)
画面の入力フォームから入力された値を、最終的にこのテーブルに登録する想定で進めて行きます。
ですので、ますはmodels.pyに適当なテーブルを作って行きます。
vim /opt/bitnami/projects/TEST/APP_TEST/models.py
from django.db import models
# Create your models here.
class Blog(models.Model):
blogid = models.IntegerField(primary_key=True)
title = models.CharField(max_length=100)
text = models.CharField(max_length=1000)
def __str__(self):
return self.title
1-2.forms.py(上記モデルに該当するカラムを入力フォームとして表示するための設定)
fieldsで指定したフィールドが、入力フォームとして表示されます。
vim /opt/bitnami/projects/TEST/APP_TEST/forms.py
from django import forms
from .models import Blog
class BlogForm(forms.ModelForm):
class Meta:
# 対象のモデルを設定
model = Blog
# fieldsで指定したフィールドが、入力フォームとして表示される
# フォームに表示する必要がないカラム(blogidなど)は指定は不要
# すべてのフィールドを指定したい場合は、__all__を指定。
fields = ('title', 'text', )
labels = {'title':'タイトル', 'text':'テキスト', }
1-3.views.py(入力フォームを出す画面用のviews)
vim /opt/bitnami/projects/TEST/APP_TEST/views.py
from django.http import HttpResponse
from django.http import Http404
from django.shortcuts import render
from django.template import loader
from .models import Blog
from .forms import BlogForm
# ...
def edit(request):
# 上記で作成したBlogFormをインスタンス化
# (BlogFormで設定した項目のinputタグが生成されるイメージ)
form = BlogForm()
# htmlで使用できるようにcontextにformを登録
context = {'form': form,}
# contextデータを渡すと、html側で{{ form }}変数が使用できるようになる。
return render(request, 'APP_TEST/detail.html', context)
1-4.edit.html(入力フォームを表示する画面)
vim /opt/bitnami/projects/TEST/APP_TEST/templates/APP_TEST/edit.html
<form action="" method="post" >
{% csrf_token %}
{{ form.as_p }}
<button type="submit" name="submit">Submit</button>
</form>
{{ form.as_p }}とすると、各種入力項目ごとにpタグを付与してくれます。
1-5.urls.py(viewsのeditを表示させるためのURLセッティング)
vim /opt/bitnami/projects/TEST/APP_TEST/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("edit/", views.edit, name="edit"),
]
注意:path("edit/" は先頭にスラッシュをつけないこと。つけるとnot foundになっちゃうよ
1-6.画面表示
http://IPアドレス/APP_TEST/edit/
2.ModelFormのインスタンス生成について
ModelFormを継承したBlogFormは、インスタンス生成時の引数の指定によって、入力フォームに表示する内容や、DB処理で新規登録するのか、更新するのかが変わってきます。
2-1.引数なし
未入力状態の入力フォームを表示したい場合に使用
form = BlogForm()
2-2.引数 request.POST
request.POSTは、POSTされたリクエストパラメータで、それらをBlogFormにセットした形でインスタンス生成します。
form.save()をすると、DBに新規登録されます。
form = BlogForm(request.POST)
2-3.引数 instance
事前にDBからレコードを取得し(item = Blog.objects.get(pk=blogid) )、それを引数に指定すると、DBで取得した内容をBlogFormにセットした形でインスタンス生成します。
form = BlogForm(instance=item)
2-4.引数 request.POST、instance
DBから取得したレコードに対し、POSTされたリクエストパラメータを反映していくイメージで、form.save()するとDBに更新されます。
form = BlogForm(request.POST, instance=item)
3.入力フォームの値を受け取り、DBに新規レコードを登録する手順
上記の続きですが、入力フォームのパラメータを受け取り、DBに新規レコードを登録する手順についての説明です。
3-1.views.py(POSTでリクエストされた用の処理を加える)
vim /opt/bitnami/projects/TEST/APP_TEST/views.py
from django.http import HttpResponse
from django.http import Http404
from django.shortcuts import render
from django.template import loader
from .models import Blog
from .forms import BlogForm
# ...
def edit(request):
#リクエストがPOSTの場合
if request.method == "POST":
# リクエストされた内容でBlogFormインスタンスを生成
form = BlogForm(request.POST)
# フォームのバリデーションチェック
if form.is_valid():
# DB保存:BlogForm(request.POST)なので新規登録
form.save()
# リダイレクト
return redirect('APP_TEST:index')
else:
form = BlogForm()
context = {'form': form,}
return render(request, 'APP_TEST/edit.html', context)
# ...
3-2.edit.html(formのactionにPOST先のURLを設定する)
vim /opt/bitnami/projects/TEST/APP_TEST/templates/APP_TEST/edit.html
<form class="" action="{% url 'APP_TEST:edit' %}" method="post" >
{% csrf_token %}
{{ form.as_p }}
<button type="submit" name="submit">Submit</button>
</form>
3-3.urls.py(app_nameの設定を忘れずに)
vim /opt/bitnami/projects/TEST/APP_TEST/urls.py
from django.urls import path
from . import views
# 上記edit.htmlでアプリ名のnamespaceを使用しているので、
# app_nameの設定を忘れずに
# <form class="" action="{% url 'APP_TEST:edit' %}" method="post" >
#
app_name = 'APP_TEST'
urlpatterns = [
path("", views.index, name="index"),
path("edit/", views.edit, name="edit"),
]
4.登録済みのデータを表示し更新処理をする
4-1.views.py(登録済みのデータの表示とDB更新処理を作成)
# リクエストパラメータとして、blogidを受け取る
def detail(request, blogid):
# blogidをPKにしてDB取得
item = Blog.objects.get(pk=blogid)
#リクエストがPOSTの場合
if request.method == "POST":
# DB取得した値をベースにPOSTされたリクエスト内容でインスタンス生成
form = BlogForm(request.POST, instance=item)
# フォームのバリデーションチェック
if form.is_valid():
# DB保存:BlogForm(request.POST, instance=item)なので更新処理
form.save()
return redirect('APP_TEST:index')
#リクエストがPOST以外の場合
# DB取得した内容でBlogFormインスタンスを生成
#(フォーム入力画面ではDB取得した内容でプリセットされているイメージ)
form = BlogForm(instance=item)
# htmlで変数として使用できるように設定
context = {'form': form, 'blogid': blogid}
return render(request, "APP_TEST/detail.html", context )
4-2.detail.html(detailにPOSTする用のテンプレートを作成)
vim /opt/bitnami/projects/TEST/APP_TEST/templates/APP_TEST/detail.html
<form class="" action="{% url 'APP_TEST:detail' blogid %}" method="post" >
{% csrf_token %}
{{ form.as_p }}
<button type="submit" name="submit">Submit</button>
</form>
4-3.urls.py( edit/1/みたいに遷移できるようにする)
vim /opt/bitnami/projects/TEST/APP_TEST/urls.py
from django.urls import path
from . import views
app_name = 'APP_TEST'
urlpatterns = [
path("", views.index, name="index"),
path("edit/", views.edit, name="edit"),
# edit/1/みたいなURLパターンでリクエストされたら、viewsのdetailをコール
path("edit/<int:blogid>/", views.detail, name="detail"),
]
その他
その他、amazon LightsailにてDjangoを使用したWEBアプリ構築については以下となります。(こちらの記事は以下記事の続きとなります。)
この記事が気に入ったらサポートをしてみませんか?