Python
 Computer >> コンピューター >  >> プログラミング >> Python

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:両方のフォームのバリデーションが通ったかどうかを検証し、フォームデータを保存する処理を記述します。

出力結果


Djangoで単一のビューを使って複数のフォームを同時に処理する方法


  1. 【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(販売台数

  2. PandasとMatplotlibで複数の時系列DataFrameを1つのグラフにまとめて描画する方法

    Pandasを使えば、複数の時系列データフレーム(DataFrame)を1つのプロットにまとめて描画できます。本記事では、ルピーとドルという2つの異なるスケールの時系列データを、左右のY軸を使い分けながら1つのグラフ上に表示する具体的手順を、サンプルコードとともに解説します。 実装の流れ 図のサイズを設定し、サブプロット間および周囲の余白(パディング)を調整する 時系列データを含むPandasデータフレームを作成する プロット用に日付をインデックスとして設定する 「rupees(ルピー)」と「dollar(ドル)」の2つの系列を同じ図上にプロットする show()メソッドを呼び出して図を表