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

