Djangoで単一のビューを使って複数のフォームを同時に処理する方法
Web開発をしていると、1つの関数やビューの中で複数のフォームを処理したい場面に出くわすことがあります。この記事では、2つのフォームを同じビュー内で同時に扱うための実装方法を解説します。この手法は多くの場面で役立ちますし、考え方を応用すれば3つ以上のフォームにも対応できます。
事前準備
まずDjangoプロジェクトとアプリを作成します。ここではプロジェクト名を「multipleFormHandle」、アプリ名を「formhandlingapp」としました。
続いて、settings.pyのINSTALLED_APPSにアプリを追加し、プロジェクトのurls.pyにアプリのURLを含めるなど、基本的な設定を行ってください。
次に、アプリ内にforms.pyを作成し、アプリディレクトリ直下に「templates」フォルダを用意します。その中にhome.htmlを配置しておきましょう。
そして、今回のキーとなるmulti_form_viewライブラリをインストールします。
pip install multi_form_view
実装例
urls.py(アプリ側)
from django.urls import path,include
from . import views
urlpatterns = [
path('',views.SchoolData.as_view(),name='home'),
]
ここではURLルーティングを設定し、後ほど作成するクラスベースビュー「SchoolData」を「home」という名前で登録しています。
models.py
from django.db import models
# Create your models here.
class StudentData(models.Model):
name=models.CharField(max_length=100)
standard=models.CharField(max_length=100)
section=models.CharField(max_length=100)
class TeachertData(models.Model):
name=models.CharField(max_length=100)
ClassTeacherOF=models.CharField(max_length=100)
Salary=models.CharField(max_length=100)
フォームから入力されたデータをデータベースに保存するため、「生徒(StudentData)」と「教師(TeachertData)」の2つのモデルを作成しました。
forms.py
from django import forms
from .models import TeachertData,StudentData
class StudentForm(forms.ModelForm):
class Meta:
model=StudentData
fields="__all__"
class TeacherForm(forms.ModelForm):
class Meta:
model=TeachertData
fields="__all__"
ここでは、ビューからフロントエンドへ描画するためのモデルフォームを2つ作成しています。
home.html
<!DOCTYPE html>
<html>
<head>
<title>tut</title>
</head>
<body>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<label><h3>Teacher</h3></label>
// ビューからフォーム1を取得して表示
{{ forms.teacher_form.as_p }}
<label><h3>Student</h3></label>
// ビューからフォーム2を取得して表示
{{ forms.student_form.as_p }}
<input type="submit" value="submit"/>
</form>
</body>
</html>
これがフロントエンド部分です。単一の<form>要素の中に2つのDjangoフォームを描画し、1つの送信ボタンでまとめて送信できるようにしています。
今回は概念と実装方法の理解が目的のため、CSSによるスタイリングは省略します。
views.py
from django.shortcuts import render
from .forms import StudentForm,TeacherForm
from django.views.generic.list import ListView
from django.urls import reverse
from multi_form_view import MultiModelFormView
# Create your views here.
class SchoolData(MultiModelFormView):
form_classes = {
'student_form' : StudentForm,
'teacher_form' : TeacherForm,
}
template_name = 'home.html'
def get_success_url(self):
return reverse('home')
def forms_valid(self, forms):
student = forms['student_form'].save(commit=False)
teacher=forms['teacher_form'].save(commit=False)
return super(SchoolData, self).forms_valid(forms)
ここが本記事の核心部分です。MultiModelFormViewを継承したクラスビュー「SchoolData」を作成し、描画する2つのフォーム(生徒フォームと教師フォーム)を辞書形式でform_classesに定義しています。
- template_name:使用するHTMLテンプレートを指定します。
- get_success_url:フォーム送信が成功した際のリダイレクト先を定義します。
- forms_valid:両方のフォームのバリデーションが通ったかどうかを検証し、フォームデータを保存する処理を記述します。
出力結果

-
【Python】複数のCSVファイルを1つのPandasデータフレームに結合する方法
複数のCSVファイルを1つのデータフレームにまとめる基本手法 複数のCSVファイルを1つのPandasデータフレームに結合したい場合、read_csv()とpd.concat()を組み合わせるのが最もシンプルで効率的な方法です。まずは、必要なPandasライブラリをインポートしましょう。ここでは、エイリアスとして「pd」を設定します。 import pandas as pd サンプルとなるCSVファイル 今回は、以下の2つのCSVファイルを例に説明します。 Sales1.csv Sales2.csv どちらのファイルにも「Car(車種)」「Place(地域)」「UnitsSold(販売台数
-
PandasとMatplotlibで複数の時系列DataFrameを1つのグラフにまとめて描画する方法
Pandasを使えば、複数の時系列データフレーム(DataFrame)を1つのプロットにまとめて描画できます。本記事では、ルピーとドルという2つの異なるスケールの時系列データを、左右のY軸を使い分けながら1つのグラフ上に表示する具体的手順を、サンプルコードとともに解説します。 実装の流れ 図のサイズを設定し、サブプロット間および周囲の余白(パディング)を調整する 時系列データを含むPandasデータフレームを作成する プロット用に日付をインデックスとして設定する 「rupees(ルピー)」と「dollar(ドル)」の2つの系列を同じ図上にプロットする show()メソッドを呼び出して図を表