Wagtailで超簡単なイベント予約サイトを作る③

こんにちは。

Wagtailで超簡単なイベント予約サイトを以下流れでご紹介していきたいと思います。今回は「③予約登録処理」について記載します。

流れ
  1. イベント一覧とイベント詳細ページを作成する
  2. 予約ページを作成する
  3. 予約登録処理
  4. 予約完了メール送信
  5. 予約確認とキャンセル処理を作成する

①②については以下を参照してください。

Wagtailで超簡単なイベント予約サイトを作る①

2021.02.28

Wagtailで超簡単なイベント予約サイトを作る②

2021.03.01

今回作るもの

前回作成した予約フォームに入力して、「予約する」ボタンを押下すると登録処理とメール送信を行います。

処理が終わったら以下メッセージを表示します。

予約登録情報と②予約登録履歴情報のモデル定義

登録するときに、①予約登録情報と②予約登録履歴情報の2つ登録していきたいと思います。キャンセルをした場合は①予約登録情報から消してしまうので、その情報を②予約登録履歴情報に残していくのが目的です。

まずは①予約登録情報のモデルをevent/models.pyに定義します。

class BookingInfo(ClusterableModel):

    # 予約するイベント
    event = models.ForeignKey(
        EventDetailPage,
        on_delete=models.CASCADE,
        blank=True,
        null=True,    )

    # 予約するユーザ
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
    )

    # 予約者名前(氏)
    first_name = models.CharField(
        max_length=30,        
    )

    # 予約者名前(名)
    last_name = models.CharField(
        max_length=30,         
    )

    # 予約者 電話番号
    phone = models.CharField(
        verbose_name="電話番号",
        max_length=20,
    )

    # 予約者 郵便番号
    zip_code = models.CharField(
        verbose_name="郵便番号",
        max_length=8,
        blank=True,
        null=True,
    )

    # 予約者 都道府県
    address1 = models.CharField(
        verbose_name="都道府県",
        max_length=40,
        blank=True,
        null=True,
    )

    # 予約者 市区町村番地
    address2 = models.CharField(
        verbose_name="市区町村番地",
        max_length=256,
        blank=True,
        null=True,
    )

    # 予約者 建物名
    address3 = models.CharField(
        verbose_name="建物名",
        max_length=256,
        blank=True,
        null=True,
    )

    # 予約日
    bookdate = models.DateTimeField(
        verbose_name="予約日",
        blank=True,
        null=True,
    )

    panels = [
        FieldPanel("first_name"),
        FieldPanel("last_name"),
        FieldPanel("zip_code"),
        FieldPanel("address1"),
        FieldPanel("address2"),
        FieldPanel("address3"),
        FieldPanel("phone"),
    ]

    class Meta:
        unique_together = [
            ("event", "user"),
        ]

    def __str__(self):
        return f"Booking {self.id}"

次に②予約登録履歴情報のモデルを同じくevent/models.pyに定義します。

class BookingHistory(ClusterableModel):

    # 登録日
    registdate = models.DateTimeField(
        verbose_name="登録日",
    )

    # イベント
    status = models.CharField(
        max_length=10,
    )

    # イベント
    event = models.ForeignKey(
        EventDetailPage,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
    )

    # ユーザ
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
    )

    # 予約者名前(氏)
    first_name = models.CharField(
        max_length=30,
        blank=True,
        null=True,            
    )

    # 予約者名前(名)
    last_name = models.CharField(
        max_length=30,
        blank=True,
        null=True,             
    )

    # 予約者 郵便番号
    zip_code = models.CharField(
        verbose_name="郵便番号",
        max_length=8,
        blank=True,
        null=True,
    )

    # 予約者 都道府県
    address1 = models.CharField(
        verbose_name="都道府県",
        max_length=40,
        blank=True,
        null=True,
    )

    # 予約者 市区町村番地
    address2 = models.CharField(
        verbose_name="市区町村番地",
        max_length=256,
        blank=True,
        null=True,
    )

    # 予約者 建物名
    address3 = models.CharField(
        verbose_name="建物名",
        max_length=256,
        blank=True,
        null=True,
    )

    # 予約者 電話番号
    phone = models.CharField(
        verbose_name="電話番号",
        max_length=256,
        blank=True,
        null=True,
    )

    # 送信アドレス
    email = models.EmailField(
        blank=True,
        null=True,             
    )

    def __str__(self):
        return f"BookingHistory {self.id}"

登録処理

次に登録処理を作っていきます。

event/urls.pyのurlpatternsに以下を追加します。

urlpatterns = [
    ...
    path("booking//",
         views.booking,
         name="booking"
         ),
    ...
]

event/views.pyに以下登録処理を追加します。前回のbook_confirm.htmlの「予約する」から呼び出される部分になります。

def booking(request, event_id):
    if request.user.is_authenticated:
        event = get_object_or_404(EventDetailPage, pk=event_id)

        bookinginfo = request.POST.copy()
        form = BookingInfoForm(bookinginfo)

        if form.is_valid():
            
            # 予約内容を登録
            bookinginfo = form.save(commit = False)
            bookinginfo.event = event
            bookinginfo.user = request.user
            bookinginfo.bookdate = timezone.now()
            bookinginfo.save()

            # 予約内容を履歴に登録
            bookingdata = BookingHistory.objects.create(
                registdate = timezone.now(),
                status = STATUS.BOOKING,
                event = bookinginfo.event,
                user = request.user,
                first_name = bookinginfo.first_name,
                last_name = bookinginfo.last_name,
                zip_code = bookinginfo.zip_code,
                address1 = bookinginfo.address1,
                address2 = bookinginfo.address2,
                address3 = bookinginfo.address3,
                email = bookinginfo.user.email,
            )

        return render(
            request,
            template_name="event/book_confirm_done.html",
            context={'event': event},
        )

    else:
        return HttpResponse('ログインしていません。', status=403)

登録完了Template

登録完了用のテンプレートbook_confirm_done.htmlを用意します。メール送信はまだしておりませんが、メール送信したとして、テンプレートを用意しておきます。

{% extends 'base.html' %}

{% load account %}

{% block content %}
<div class="container">
    <div class="row my-5">
        <div class="col-12">
            <h4 class="display-6 text-center">ご予約受付完了しました</h4>
        </div>
    </div>

    <div class="row m-5">
        <p>ご予約ありがとうございました。
            {% if user.is_authenticated %}
                {{ user.email }}に予約内容をお送りしました。
            {% endif %}
        </p>
    </div>
</div>

{% endblock %}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)