#1 はじめに
Djangoの1回目、2回目で作ったものをベースに、今回は掲示板などの入力フォームを定義して、フォームに入力したデータをデータベースに保存するテクニックについて紹介をしたいと思います。(内容の利用については自己責任でお願いします)
#2 参照すべきサイト
Djangoの解説サイト(日本語)にフォームについて丁寧な解説があるので、ざっと目を通してみることをお勧めします。少し難しく感じる方もいらっしゃるかもしれませんが、これをみて感じをつかんでください。
また、もしかしたらDjango GirlsのDjangoフォームに関する記事の方が読みやすいかもしれません。
#3 forms.pyの作成
models.pyと同じディレクトリ にforms.pyを作成します。
モデルは、models.pyで定義したArticleモデルをそのまま使います。また、フォームで表示させるフィールドを定義します。
from django.forms import ModelForm
from .models import Article
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ["pub_date","headline","content","reporter"]
#4 views.pyの編集
views.pyに新しい関数formtestを追加します。
この関数は、最初にGETメソッドで呼び出した時(else:)は、formとしてArticleFormを呼び出し、form.htmlを使って入力フォームが表示されるようにレンダリングをします。
その後、フォームを入力して送信ボタンを押すとPOSTメソッドでリクエストが送られるので(if request.method == 'POST')、formとして、入力したデータ(request.POST)が入ったフォームを定義します。そして、フォームのバリデーションが正常であれば(if form.is_valid)、モデルArticleのインスタンスを作成し、そこにデータを入れていきます。そして、最後に.save()をしてデータをデータベースに保存します。
これをコードにしたものが以下になります。必要なモジュールのインポートも忘れないようにしましょう。
from django.http.response import HttpResponseNotAllowed
from django.http import HttpResponse
from django.shortcuts import render, redirect
from .models import Reporter, Article
from .forms import ArticleForm
def hello(request):
hw = 'Hello World!'
return render(request, 'base.html', {'object':hw})
def modeltest(request):
object_list = Article.objects.all()
return render(request, 'modeltest.html', {'object_list':object_list})
def formtest(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
article = Article()
article.pub_date = form.cleaned_data['pub_date']
article.headline = form.cleaned_data['headline']
article.content = form.cleaned_data['content']
article.reporter = form.cleaned_data['reporter']
article.save()
return redirect('modeltest')
else:
form = ArticleForm()
return render(request, 'form.html', {'form': form})
レンダリングに必要なHTMLファイルは以下になります。{%csrf_token%}はクロスサイトリクエストフォージェリーというサイバー攻撃の一種を防ぐためにあらかじめDjangoが用意してくれている「おまじない」になります。これを入れていないとエラーが出ますので、忘れないようにしてください。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>フォーム</title>
</head>
<body>
<h1>ユーザーフォーム</h1>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">送信</button>
</form>
</body>
</html>
#5.urls.pyの設定
formtest/にアクセスするとviews.pyの関数formtestが呼び出されるようにurls.pyを設定しておきます。
from django.urls import path
from .views import hello, modeltest, formtest
urlpatterns = [
path('hello/', hello, name='hello'),
path('modeltest/', modeltest, name = 'modeltest'),
path('formtest/', formtest, name = 'formtest')
]
これで準備は終わりました。それでは実際にウェブサイトにアクセスしてみましょう。
127.0.0.1:8000/formtest/にアクセスして適当にデータを入力して、ボタンを押すと、127.0.0.1:8000/modeltest/に飛んで以下が表示されるはずです。
object_list:<QuerySet [<Article: テスト>, <Article: テスト2>, <Article: テスト3>]>
item:テスト
item.pub_date:July 25, 2021
item.headline:テスト
item.content:これはテストです。
item.reporter:投稿者1
item:テスト2
item.pub_date:July 25, 2021
item.headline:テスト2
item.content:test2
item.reporter:投稿者1```