【django】お問い合わせフォームを実装する方法 (CreateView)

webサービスにおいてお問い合わせフォームは必要不可欠です

しかし,お問い合わせフォームはHTMLで表現するだけでなく,モデルの作成や送信フォームの設置と難易度が上がります

本記事では,djangoのCreateViewを使ってお問い合わせフォームを簡単に作成する方法について解説します

目次

models.pyにお問い合わせ用のモデルを作る

まずはお問い合わせした内容をデータベースに保存するためにモデルを定義しましょう

models.pyにお問い合わせ題目,内容,email,日付(自動)のカラムを作りました

class Contact(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    date = models.DateField(auto_now_add=True)
    email = models.EmailField(max_length=200)

    def __str__(self):
        return self.title

    class Meta:
        db_table = 'contacts'

データベースにモデルの変更を反映する

モデルで新しいテーブルを定義したら,それをdjango本体に教えてあげます

データベースへの変更の反映
  1. migrationsファイルを作成する
  2. migrateして反映する

migrationsファイルを作成する

django本体のmigrationsフォルダに変更したことを知らせるファイルを作成します

下記のコマンドをcommand promptで実行します

python manage.py makemigrations blog

うまくいくとこのように表示されます

Migrations for 'blog':
  blog\migrations\0002_contact.py
    - Create model Contact  

変更をmigrateでデータベースに反映する

モデルの変更内容をdjangoのデータベースに反映します

以下コマンドをcommand promptに打ち込んでください

python manage.py migrate

失敗しなければこのようになります

Operations to perform:
  Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
  Applying blog.0002_contact... OK

blog.0002_contact.pyに記載されている変更箇所がデータベースに反映されたということ意味になります

forms.pyを作ってフォームを作成

自身のアプリケーションフォルダ(本記事ではblog)にforms.pyを新規作成してください

formの管理はこちらで行います

このフォームはModelFormを継承して作成します

モデルのカラムから入力項目が増えないのであればこちらを使うと素早く記述できちゃいます

from django import forms
from .models import Contact

class ContactForm(forms.ModelForm):
    class Meta:
        model = Contact
        fields = ['title', 'email' , 'content']
        labels = {
           'title':'題目',
           'email': 'メールアドレス',
           'content':'内容',
        }

fieldsに入力項目を指定しています

models.pyで指定したカラム名と同じ名称になるようにしてください

views.pyにCreateViewを作る

お問い合わせをしたらデータベースに書き込むようにCreateViewを作ります

この際にforms.pyで定義したフォームを取り込みます

from django.views.generic.edit import CreateView
from .forms import ContactForm
from django.urls import reverse_lazy
from .models import Contact

class ContactFormView(CreateView):
    template_name = 'blog/contact.html'
    form_class = ContactForm
    success_url = reverse_lazy('home')
    model = Contact

import部分のCreateViewですが,TemplateViewとは住所が違うので,気を付けてください

urls.pyにURLを追加する

アプリケーション側のurls.pyに先ほどviews.pyで作成したViewを読み込んで,url指定しましょう

最後にカンマがあることを忘れずに気をつけてください

from django.urls import path
from .views import HomeTemplateView, ContactFormView

urlpatterns = [
    path('', HomeTemplateView.as_view(), name='home'),
    path('contact/', ContactFormView.as_view(), name='contact'), # カンマあります
]

HTMLでお問い合わせフォームを描画する

CreateViewでtemplate_nameをcontact.htmlとしたので,それを新規作成します

<form method="POST" class="mx-3 mx-md-5">{% csrf_token %}
	{{form}}
	<div>
		<button type="submit">送信</button>
	</div>
</form>

お問い合わせして動作をみる

フォームが作成されたので,アクセスしてみましょう

python manage.py runserver

アクセス先はurls.pyで指定したURLです

http://127.0.0.1:8000/contact/

default_form

入力するとsuccess_urlで設定したところに飛ばされたと思います

実際に入力されたか確認するにはadminにモデルを登録しましょう

from django.contrib import admin

from .models import Blog, Contact

admin.site.register(Blog)
admin.site.register(Contact)

これでhttp://127.0.0.1:8000/admin/にアクセスします

Contentsのところに書き込まれていると思います

admin_contact

とりあえず完成です.お疲れ様でした

Bootstrapでdjangoのformの見た目をどうにかする

このままではダサすぎて天を見上げても星が一つもありません

Bootstrapを使い,それっぽくします

<main>
    <div class="container mt-5">
        <div class="text-center mb-5">
            <h1 class="mb-5 mt-3">お問い合わせ</h1>
            <form method="POST" class="mx-3 mx-md-5">{% csrf_token %}
                {% for item in form %}
                <div class="form-group mb-3 fs-5">
                    <label for="{{item.id_for_label}}">{{item.label}}</label>
                    {% if item.name == "content" %}
                    <textarea class="form-control" {% if item.field.required %}required{% endif %} name="{{item.name}}" id="{{item.id_for_label}}" rows="3"></textarea>
                    {% else %}
                    <input type="{{item.field.widget.input_type}}" class="form-control" 
                        {% if item.field.required %}required{% endif %} 
                        name="{{item.name}}" id="{{item.id_for_label}}">
                    {% endif %}
                </div>
                {% endfor %}
                <div class="py-3">
                    <button class="btn btn-success btn-lg w-100" type="submit">送信</button>
                </div>
            </form>
        </div>
    </div>
</main>

圧倒的にそれっぽくなりました

参考文献

下記にCreateViewに関する公式ドキュメントと関連記事をまとめているので,参考にしてください

CreateViewの公式ドキュメント

successリダイレクト時にメッセージを表示する

Bootstrap5を組み込んでデザインを簡単に整える

お疲れ様でした

シェアしてくださると嬉しいです!
  • URLをコピーしました!

コメント

コメントする

目次