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

こんにちは。

Wagtailで超簡単なイベント予約サイトを以下流れでご紹介していきたいと思います。今回は「②予約ページを作成する」について記載します。

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

①については、以下をご覧ください。

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

2021.02.28

参加者入力フォームの作成

前回作った「イベント詳細ページ」の「予約へ進む」ボタンから参加者入力フォームを表示します。

上の赤枠のボタンを押下すると、以下ページに進みます。

まず(project)/urls.pyのurlpatternsに追加します。

urlpatterns = [
    ...
    path('', include('event.urls')),
]

event/urls.pyを作成して、以下を追加します。eventのurlはこちらに登録していくようにします。

from django.urls import path
from . import views

app_name = "event"

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

event/forms.pyを作成して、入力フォームを作成します。

from django import forms
from .models import BookingInfo

class BookingInfoForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(BookingInfoForm, self).__init__(*args, **kwargs)

    class Meta:
        model = BookingInfo
        fields = [
            "first_name",
            "last_name",
            "phone",
            "zip_code",
            "address1",
            "address2",
            "address3",
        ]

        labels = {
            "first_name": "名前(姓)",
            "last_name": "名前(名)",
            "phone": "電話番号",
            "zip_code": "郵便番号",
            "address1": "都道府県",
            "address2": "市区町村番地",
            "address3": "建物名",
        }

次にevent/views.pyを作成して、以下を追加します。予約人数をチェックしたり、既に予約済みかのチェックをしています。

def book_confirm(request, event_id):
    event = get_object_or_404(EventDetailPage, pk=event_id)
    form = BookingInfoForm()

    numbooking = BookingInfo.objects.filter(event=event_id).count()
    numuser = BookingInfo.objects.filter(event=event_id,user=request.user).count()
    errmsg = ""
    if numbooking >= event.capacity:
        errmsg = "申し訳ありません。定員のためご予約出来ません。"

    if numuser >=1:
        errmsg = "既にご予約済みです。"

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

最後にbook_confirm.htmlを作成して、以下を追加します。

{% extends "base.html" %}

{% load wagtailcore_tags widget_tweaks %}

{% block extra_js %}
<script src="https://yubinbango.github.io/yubinbango/yubinbango.js" charset="UTF-8"></script>
{% endblock %}

{% block content %}
<div class="container">
    <div class="row">
        <div class="col-lg-8 col-md-10 mx-auto">
            <h4>予約内容確認</h4>
            <table class="table table-hover table-striped">
                <tbody>
                    <tr>
                        <th scope="row">予約イベント</th>
                        <td>
                            {{ event.title }}
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">日時</th>
                        <td>
                            {% if event.creation_date %}
                                {{ event.creation_date|date:"y/n/j H:i" }}
                            {% endif %}
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">場所</th>
                        <td>
                            {% if event.zip_code %}
                                〒{{ event.zip_code }}
                            {% endif %}
                            {% if event.address1 %}
                                {{ event.address1 }}
                            {% endif %}
                            {% if event.address2 %}
                                {{ event.address2 }}
                            {% endif %}
                            {% if event.address3 %}
                                {{ event.address3 }}
                            {% endif %}
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">参加費</th>
                        <td>
                            {% if event.price %}
                                {{ event.price }}円
                            {% endif %}  
                        </tr>
                    </tr>
                </tbody>
            </table> 
        </div>
    </div>

    <div class="row m-5">
        <div class="col-md-6 mt-md-2 mt-0 mx-auto">
            <!-- class="h-adr" yubinbango.jsに必要-->
            <form method='POST' action='{% url 'event:booking' event.id %}' class="h-adr"> 
                {% csrf_token %}

                <span class="p-country-name" style="display:none;">Japan</span>

                {% for field in form %}
                    <div class="row">
                        <div class="col-sm-12">
                            {% if field|widget_type == 'textarea' %}
                                <div class="form-group">
                                    {% render_field field class+="form-control" rows="6" placeholder=field.label %}
                                    {% if field.errors %}
                                        <small class="d-block text-danger text-small cc-font-light">
                                            {% for err in field.errors %}
                                            * {{ err|escape }}{% if not forloop.last %}<br />{% endif %}
                                            {% endfor %}
                                        </small>
                                    {% endif %}
                                    {% if field.help_text %}
                                        <small class="form-text text-muted cc-font-light">{{ field.help_text|safe }}</small>
                                    {% endif %}
                                </div>
                            {% else %}
                                {% if field.label != '' %}
                                    <div class="form-group">
                                        {% render_field field class+="form-control" placeholder=field.label %}
                                        {% if field.errors %}
                                            <small class="d-block text-danger text-small cc-font-light">
                                                {% for err in field.errors %}
                                                * {{ err|escape }}{% if not forloop.last %}<br />{% endif %}
                                                {% endfor %}
                                            </small>
                                        {% endif %}
                                        {% if field.help_text %}
                                            <small class="form-text text-muted cc-font-light">{{ field.help_text|safe }}</small>
                                        {% endif %}
                                    </div>
                                {% endif %}
                            {% endif %}
                        </div>
                    </div>
                {% endfor %}
            
                <div class="text-right">
                    {% if user.is_authenticated %}                      
                        {% if not errmsg %}
                            <div class="form-group">
                                <input type="submit" class="btn btn-success" value="予約する">
                            </div>
                        {% else %}
                            <div class="form-group">
                                <input type="" class="btn btn-success disabled" value="予約する">
                            </div>
                            {{ errmsg }}
                        {% endif %}
                    {% else %}
                        <div class="form-group">
                            <input type="" class="btn btn-success disabled" value="予約する">
                        </div>
                        予約するにはログインをお願いします。
                        <a href="{% url 'account_signup' %}">新規登録</a>
                        <a href="{% url 'account_login' %}">ログイン</a>
                    {% endif %}
                </div>             
            </form>
        </div>
    </div>
</div>

{% endblock %}

コメントを残す

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

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