Djangoのforms.Formでフォームの結果をモデルに保存する方法
Djangoのforms.Formでフォームの結果をモデルに保存する方法をご紹介します。
フォームで入力した内容をモデルに保存する場合、「forms.ModelForm」を用いると簡単です。
しかし、ここではあえて「FormView」と「forms.Form」を使用します。
目次
条件
- Django 3.0.7
- Python 3.7.0
models.py
models.pyに以下のようにPostクラスを追加します。
from django.db import models class Post(models.Model): """投稿モデル""" class Meta: db_table = 'post' title = models.CharField(verbose_name='タイトル', max_length=10) comment = models.CharField(verbose_name='コメント', max_length=100) created_at = models.DateTimeField(verbose_name='登録日時', auto_now_add=True) updated_at = models.DateTimeField(verbose_name='更新日時', auto_now=True) def __str__(self): return self.title + ',' + self.comment
urls.py
トップ画面にフォーム画面を表示します。
from django.urls import path from . import views app_name = 'sampleApp' urlpatterns = [ # トップ画面 path('', views.TestView.as_view(), name='index'), ]
forms.py
「forms.Form」のTestFormクラスを定義します。
from django.forms import forms, CharField from sampleApp.models import Post class TestForm(forms.Form): title = CharField( initial='', label='タイトル', max_length=10, required=True, # 必須 ) comment = CharField( initial='', label='コメント', max_length=100, required=True, # 必須 ) def save(self): # save data using the self.cleaned_data dictionary data = self.cleaned_data post = Post(title=data['title'], comment=data['comment']) post.save()
views.py
「FormView」を用います。
from django.contrib import messages from django.views.generic.edit import FormView from sampleApp.forms import TestForm class TestView(FormView): template_name = 'sampleApp/index.html' form_class = TestForm success_url = '/' # リダイレクト先URL def form_valid(self, form): form.save() # 保存処理など messages.add_message(self.request, messages.SUCCESS, '登録しました!') # メッセージ出力 return super().form_valid(form)
テンプレート
index.htmlに、「メッセージ」と「フォーム」を表示するようにします。
{% extends 'base.html' %} {% block content %} <h2>フォームサンプル</h2> {% if messages %} <ul class="messages"> {% for message in messages %} <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li> {% endfor %} </ul> {% endif %} <form method="post">{% csrf_token %} {{ form.as_p }} <input type="submit" value="送信"> </form> {% endblock %}
実行結果
実行前
DBには1レコードのみが存在する状態です。
フォームに値を入力して、送信ボタンを押します。
実行後
views.pyのsuccess_urlで指定したURL(今回はフォームのURLと同一)にリダイレクトして、
「登録しました!」というメッセージが表示されます。
DBに新しいレコードが追加されていることがわかります。
参考
Django公式:FormView
https://docs.djangoproject.com/ja/3.0/ref/class-based-views/generic-editing/#formview
Django公式:フォームとフィールドの検証
https://docs.djangoproject.com/ja/3.0/ref/forms/validation/#form-and-field-validation
Django公式:メッセージフレームワーク
https://docs.djangoproject.com/ja/3.0/ref/contrib/messages/#module-django.contrib.messages
stackoverflow:How do you write a save method for forms in django?
https://stackoverflow.com/questions/11943912/how-do-you-write-a-save-method-for-forms-in-django
Django Girls:Djangoフォーム
https://tutorial.djangogirls.org/ja/django_forms/