1
1

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 3 years have passed since last update.

Djangoのフォーム(forms.py)を使ってデータを作成し、記録する(基礎の基礎3)

Posted at

#1 はじめに
Djangoの1回目2回目で作ったものをベースに、今回は掲示板などの入力フォームを定義して、フォームに入力したデータをデータベースに保存するテクニックについて紹介をしたいと思います。(内容の利用については自己責任でお願いします)

#2 参照すべきサイト
Djangoの解説サイト(日本語)にフォームについて丁寧な解説があるので、ざっと目を通してみることをお勧めします。少し難しく感じる方もいらっしゃるかもしれませんが、これをみて感じをつかんでください。

また、もしかしたらDjango GirlsのDjangoフォームに関する記事の方が読みやすいかもしれません。

#3 forms.pyの作成
models.pyと同じディレクトリ にforms.pyを作成します。
モデルは、models.pyで定義したArticleモデルをそのまま使います。また、フォームで表示させるフィールドを定義します。

forms.py
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()をしてデータをデータベースに保存します。

これをコードにしたものが以下になります。必要なモジュールのインポートも忘れないようにしましょう。

views.py
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が用意してくれている「おまじない」になります。これを入れていないとエラーが出ますので、忘れないようにしてください。

form.html
<!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を設定しておきます。

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```
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?