Python Webシステム 会議室予約システム

Djangoフレームワークを使った会議室予約システムの作成(更新削除)

こんにちは、ともです。

今回はPythonのWebアプリケーション用フレームワークのDjangoを使って会議室予約システム作成の続きになります。

前回までの内容は以下を参照してください。

目次

  1. フロントデザイン修正
    1. templates/resurv.htmlコーディング
    2. mrrs/forms.pyコーディング
    3. mrrs/views.pyコーディング
  2. まとめ

フロントデザイン修正

フロントのデザインを修正します。

templates/resurv.htmlコーディング

画面デザインを修正します。

    

<!DOCTYPE html>
<html>
  <head lang="ja">
    <meta charset="utf-8">
    <title>会議室予約システム</title>
    <!-- google fontsを使用するためgoogleからフォントのcssを取得します。-->
    <link href="https://fonts.googleapis.com/css?family=Courgette|Noto+Serif+JP&display=swap" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

    <!-- css のスタイルを記述します。 今後cssは外部ファイル化を行います。 start -->
    <style>
      /** CSS はhtmlのtag class id の有効範囲が大きいものから記載します。 */
      /** ************************************************** */
      /** tag                                                */
      /** ************************************************** */

      /** h1タグのスタイルです */
      h1 {
        font-size  : 40px;                     /* h1タイトルのフォントサイズです */
        font-family: 'Courgette', cursive;     /* googleフォントです */
        text-align : center;                   /* 文字の中央よせです */
      }

      /** ************************************************** */
      /** class                                              */
      /** ************************************************** */

      /** wrapper のスタイルです */
      /** bodyタグでもいいですが wrapperを使うことで全体的にpaddingやmarginの調整をとりやすくします */
      .wrapper {
        max-width  : 1200px;                   /* 最大横幅です */
        min-width  : 700px;                    /* 最小横幅です レスポンシブ対応ではないです */
        margin     : 0 auto;                   /* 外側を操作します。 中央よせをします 0が上下 autoが左右 */
        padding    : 40px;                     /* 内側を操作します。 上下左右で内側に40pxの余白を付けます */
      }

      /** reserveのwrapperを使うことでreserveにpaddingやmarginの調整をとりやすくします */
      .reserve_wrapper {
         padding   : 50px;                     /* 内側を操作します。 上下 50px 左右200px で内側に余白を付けます */
      }


      /** -------------------------------------------------- */
      /** 入力フォーム                                       */
      /** -------------------------------------------------- */
      /** reserveのinput部分で使用します */
      .reserve_input {
        border-radius : 12px;                  /* 枠に丸みを付けます */
        box-sizing : border-box;
        border     : 1px solid #465DAA;
                                               /* 枠線を表示します */
        padding    : 20px;                     /* 内側を操作します。 上下左右 50px で内側に余白を付けます */
        margin     : 50px 50px;               /* 外側を操作します。 上下 50px 左右200px で外側に余白を付けます */
      }

      /** reserveのinput部分で入力の部品を囲みます */
      .reserve_input_div {
        position   : relative;                 /* reserve_input からみて相対的な位置を設定します。 positionのデフォルトは staticです */
        margin     : 30px 3%;                  /* 外側を操作します。 上下 30px 左右3% で外側に余白を付けます */
      }

      /** input部分で入力の部品の中の実際の部品textを選択します */
      .reserve_input_div input[type='text'] {
        font       : 16px/24px 'Noto Serif JP', serif;
                                               /* font-size/line-height googleフォントです */
        box-sizing : border-box;               /* ボックスサイズの算出方法を指定します パディングとボーダーを幅と高さに含めています */
        width      : 100%;                     /* 横幅を100%にします。*/
        letter-spacing : 1px;                  /* 文字の間隔を指定します。*/
        padding-left : 6em;                    /* 内側を操作します。 左 6em(font-sizeに合わせる) で内側に余白を付けます */
      }

      /** input部分で入力の部品の中の実際の部品textにfocusが当たったとき */
      .reserve_input_div input[type='text']:focus {
        outline    : none;                     /* focus(入力ができるようになるとき)が当たったとき 枠を表示しません */
      }

      /** 部品のclass です 今回はmrrs/form.pyに記載しています */
      .reserve_type_text {
        padding    : 4px 0;                    /* 内側を操作します。 上下 4px 左右0 で内側に余白を付けます */
        border     : 0;                        /* bordrを表示しない */
        border-bottom: 1px solid #1b2538;      /* 下線は表示する */
        background-color: transparent;         /* 背景を透過 */
      }

      /** reserve_type_text に関連する focus_lineのクラスを指定します */
      .reserve_type_text ~ .focus_line {
        position   : absolute;                 /* reserve_type_text からみて絶対的な位置を設定します。 positionのデフォルトは staticです */
        bottom     : 0;                        /* 下から0 */
        left       : 0;                        /* 左から0 */
        width      : 0;                        /* 横幅 0 */
        height     : 2px;                      /* 高さ 2px */
        transition : 0.4s;                     /* 要素の2つの状態間の変化を0.4秒で操作します */
        background-color: #da3c41;             /* 下線を赤にします */
      }

      /** reserve_type_textのforcusに関連する focus_lineのクラスを指定します */
      .reserve_type_text:focus ~ .focus_line,
      .reserve_input_div.reserve_type_text ~ .focus_line {
        width      : 100%;                     /* 横幅 100%にします */
        transition : 0.4s;                     /* 要素の2つの状態間の変化を0.4秒で操作します */
      }

      /**  reserve_type_text に関連する labelを指定します */
      .reserve_type_text ~ label {
        position   : absolute;                 /* reserve_type_text からみて絶対的な位置を設定します。 positionのデフォルトは staticです */
        z-index    : -1;                       /* labelの重なりz軸を 下にするのかな */
        top        : 4px;                      /* 上から4px */
        left       : 0;                        /* 左から0 */
        width      : 100%;                     /* 横幅 100%にします */
        transition : 0.3s;                     /* 要素の2つの状態間の変化を0.5秒で操作します */
        letter-spacing: 0.5px;                 /* 文字の間隔を指定します。*/
        color      : #aaaaaa;                  /* ラベルの文字の色を灰色っぽいいろにします */
      }

      /**  reserve_type_textのforcusに関連する labelのクラスを指定します */
      .reserve_type_text:focus ~ label,
      .reserve_input_div.reserve_type_text ~ label {
        font-size  : 12px;                     /* 文字サイズを小さくします */
        top        : -16px;                    /* 文字位置を上にします テキストの中から上に移動 */
        transition : 0.3s;                     /* 要素の2つの状態間の変化を0.4秒で操作します */
        color      : #da3c41;                  /* 赤文字 */
      }

      /** reserve_input_div_button 登録ボタンで使用します  */
      .reserve_input_div_button {
        text-align : center;                   /* 文字を中央に寄せます */
        margin     : 10px auto;                /* divを中央に寄せます */
      }

      /** submit_insert 登録ボタンのデザインです  */
      .submit_insert {
        position   : relative;                 /* reserve_input_div_button からみて相対的な位置を設定します。 positionのデフォルトは staticです */
        color      : #fff;                     /* 文字色白 */
        width      : 120px;                    /* 横幅 120px */
        height     : 50px;                     /* 高さ 50px */
        line-height: 50px;                     /* 高さ 50px */
        border-radius: 12px;                   /* 枠に丸みを付けます */
        text-align : center;                   /* 文字を中央に寄せます */
        font-family: 'Noto Serif JP', serif;   /* googleフォントです */
        font-size  : 16px;                     /* 文字のサイズです */
        background-color: #465DAA;             /* ボタンの背景色です */
        box-shadow : 0 1px 1px rgba(0, 0, 0, 0.28);
                                               /* ボックスの影を付けます */
      }

      /** モーダルです  */
      .modal{
        display    : none;                     /* 非表示にします */
        height     : 100vh;                    /* 高さを決めます(ビューの高さの割合) */
        position   : fixed;                    /* 特定の場所に配置します */
        top        : 0;                        /* トップ */
        width      : 100%;                     /* 横幅 */
      }

      /** モーダル背景です  */
      .modal_bg{
        background : rgba(0,0,0,0.8);          /* 背景色 */
        height     : 100vh;                    /* 高さを決めます(ビューの高さの割合) */ 
        position   : absolute;                 /* 絶対位置に配置します */
        width      : 100%;                     /* 横幅 */
        top        : 0px;                      /* トップ */
        left       : 0px;                      /* 左 */
        z-index    : 150;                      /* レイア  */
      }

      /** モーダル背景です  */
      .modal_content {
        background : #fff;                     /* 背景色 */
        left       : 50%;                      /* 左 */
        padding    : 40px;                     /* 内側を操作します。 上下 40pxで内側に余白を付けます */
        position   : absolute;                 /* 絶対位置に配置します */
        top        : 50%;                      /* トップ */
        transform  : translate(-50%,-50%);     /* 要素の2つの状態間の変化を操作します */
        width      : 60%;                      /* 横幅 */
        z-index    : 200;                      /* レイアー */
      }

      /** モーダル */
      .js-modal-open,
      .js-modal-open-update {
        z-index    : 1;                        /* レイア  */
      }

      /** -------------------------------------------------- */
      /** リスト                                             */
      /** -------------------------------------------------- */
      /** reserveのlist部分で使用します */
      .reserve_list {
        display    : grid;                     /* gridを使います */
        border-radius : 12px;                  /* 枠に丸みを付けます */
        position   : relative;                 /* reserve_input_div_button からみて相対的な位置を設定します。 positionのデフォルトは staticです */
        box-sizing : border-box;               /* ボックスサイズの算出方法を指定します パディングとボーダーを幅と高さに含めています */
        border     : 1px solid rgba(70,93,170,1);
                                               /* 枠を付けます */
      }

      /** reserveのlist部分の行で使用します */
      .reserve_list_row {
        display    : grid;                     /* gridを使います */
        grid-template-columns : 150px 1fr;     /* 150px 1 fr*/
        background-color : #fff;               /* 文字色 */
        border-top : 1px solid rgba(70,93,170,1);
                                               /* 枠を付けます */
      }

      /** グリッドのヘッダー部分 */
      .reserve_list_row-houre {
        color      : #fff;                     /* 文字色 */
        background-color: #465DAA;
                                               /* 背景色 */
        border-bottom : 1px solid rgba(0, 0, 0, 0.1);
                                               /* 枠線 */
        grid-template-columns : 150px repeat(24, 1fr);
                                               /* 150px 1frで24時間の枠を作成 */
      }

      /** グリッドの最初部分 */
      .reserve_list_row-houre .reserve_list_row-first {
        border-top : 0;                        /* 上線 */
        background-color : #465DAA;            /* 背景色 */
      }

      /** グリッドの最初部分 のspan */
      .reserve_list_row-houre span {
        text-align : center;                   /* 文字中央よせ */
        font-size  : 12px;                     /* 文字サイズ */
        align-self : center;                   /* 中央配置 *
        font-weight: bold;                     /* 文字太さ*/
        padding    : 20px 0;                   /* 内側を操作します。 上下20px 左右0 で内側に余白を付けます */
      }

      /** グリッドのライン部分 */
      .reserve_list_row-lines {
        position   : absolute;                 /* reserve_type_text からみて絶対的な位置を設定します。 positionのデフォルトは staticです */
        height     : 100%;                     /* 高さ100% */
        width      : 100%;                     /* 横幅100% */
        background-color : transparent;        /* 背景色透過 */
        grid-template-columns : 150px repeat(24, 1fr);
                                               /* 150px 1frで24時間の枠を作成 */
      }

      /** グリッドのライン部分 のspan */
      .reserve_list_row-lines span {
        display    : block;                    /* ブロック要素にします */
        border-right : 1px solid rgba(0, 0, 0, 0.1);
                                               /* 左枠線 */
      }

      /** グリッドのライン */
      .reserve_list_row-first {
        background-color : #fff;               /* 背景色 白 */
        border-width : 1px 0 0 0;              /* 線の太さ 上*/
        border-color : rgba(0, 0, 0, 0.1);     /* 線の色 */
        border-style : solid;                  /* 実践 */
        padding    : 15px 0;                   /* 内側を操作します。 上下左右 15px で内側に余白を付けます */
        font-size  : 12px;                     /* 文字のサイズ */
        font-weight: bold;                     /* 太文字 */
        text-align : center;                   /* 中央寄せ */
        z-index: 100;
      }

      /** 文字テキスト */
      .reserve_text {
        text-align : center;                   /* 中央寄せ */
        font-family: 'Noto Serif JP', serif;   /* googleフォントです */
      }

      /** 文字テキスト */
      .reserve_list_row-bars {
        list-style : none;                     /* マーカーを外す */
        display    : grid;                     /* gridを使います */
        padding    : 9px 0;                    /* 内側を操作します。 上下左右 15px で内側に余白を付けます */
        margin     : 0;                        /* 外側を操作します。 上下左右 0px で内側に余白を付けます */
        grid-template-columns: repeat(24, 1fr);
                                               /* 150px 1frで24時間の枠を作成 */
        grid-gap   : 8px 0;                    /* グリッドの間の線 */
        border-top : 1px solid rgba(221, 221, 221, 0.8);
                                               /* 上線 */
        text-align : center;                   /* 文字の中央よせ */
      }

      /** ユーザー名 */
      .user_name {
        font-family: 'Noto Serif JP', serif;   /* googleフォントです */
        font-size  : 12px;                     /* 文字のサイズ */
        color      : #fff;                     /* 文字色 白 */
      }

      .reserve_div_button {
        display: flex;
      }

    </style>

    <script type="text/javascript" language="javascript">
      $(function() {
        $('.js-modal-open').on('click',function(){
          $('.js-modal').fadeIn();
          $('.reserve_list_row-first').css('z-index', 0);
          $('.js-modal-open-update').css('z-index', 0);
          $('#id_reserv_id').val("");
          $('#id_room_id').val("");
          $('#id_reserv_name').val("");
          $('#id_start_date_time').val("");
          $('#input_button').css('display', '');
          $('#update_button').css('display', 'none');
          $('#delete_button').css('display', 'none');

          return false;
        });
        $('.js-modal-open-update').on('click',function(){
          $('.js-modal').fadeIn();
          $('.reserve_list_row-first').css('z-index', 0);
          $('.js-modal-open').css('z-index', -1);
          $('.js-modal-open-update').css('z-index', -1);
          $('#id_reserv_id').val($(this).data('id'));
          $('#id_room_id').val($(this).data('room_id'));
          $('#id_reserv_name').val($(this).data('room_user'));
          $('#id_start_date_time').val($(this).data('start_date_time'));
          $('#id_end_date_time').val($(this).data('end_date_time'));
          $('#input_button').css('display', 'none');
          $('#update_button').css('display', '');
          $('#delete_button').css('display', '');

          return false;
        });
        $('.js-modal-close').on('click',function(){
          $('.js-modal').fadeOut();
          $('.reserve_list_row-first').css('z-index', 1);
          $('.js-modal-open').css('z-index', 1);
          $('.js-modal-open-update').css('z-index', 1);

          return false;
        });
      });
    </script>


  </head>
  <body>


    <div class="wrapper"><!-- wrapper start -->
      <header>
        <h1>Meeting room reservation system</h1>
      </header>
      <article>

          <div class="reserve_wrapper"><!-- reserve_wrapper start -->

            <!-- -------------------------------------------------- -->
            <!-- 入力 リスト                                        -->
            <!-- -------------------------------------------------- -->
            <div class="reserve_list"><!-- reserve_list start  -->
              <div class="reserve_list_row reserve_list_row-houre">

                <!-- 24時間の表記 -->
                <div class="reserve_list_row-first"></div>
                  {% for houre in ''|center:24 %}
                  <span>{{forloop.counter}}</span>
                  {% endfor %}
                </div>

                <!-- 縦線の表記 -->
                <div class="reserve_list_row reserve_list_row-lines">
                  {% for count in ''|center:24 %}
                  <span></span>
                  {% endfor %}
                </div>

                <!-- 会議室の内容 -->
                {% for reserv in reserv_data %}
                <div class="reserve_list_row">
                  <div class="reserve_list_row-first">
                    <div class="reserve_text">
                      <a class="js-modal-open" href="#">
                        会議室{{reserv.room_id}}:予約[{{reserv.id}}]
                      </a>
                    </div>
                  </div>
                  <ul class="reserve_list_row-bars">
                    <!-- 押下時値を渡す -->
                    <li class="js-modal-open-update" 
                      style="grid-column: {{reserv.start_date_time|date:'H'}}/{{reserv.end_date_time|date:'H'}}; background-color: #465DAA;"
                      data-id={{reserv.id}}
                      data-room_id={{reserv.room_id }}
                      data-room_user={{reserv.user }}
                      data-start_date_time="{{reserv.start_date_time|date:'Y-m-j H:i:s'}}"
                      data-end_date_time="{{reserv.end_date_time|date:'Y-m-j H:i:s'}}"
                    >
                      <span class="user_name">{{reserv.user}}</span>
                    </li>
                  </ul>
                </div>
                {% endfor %}
              </div>

            </div><!-- reserve_list end  -->
          </div><!-- reserve_wrapper end  -->
      </article>

      <footer></footer>

    </div><!-- wrapper end   -->

    <!-- 入力フォームと送信ボタンは formタグで囲み postメソッドで送信する -->
    <form action="" method="POST">
      <!--POSTを行う際に必要 -->
      {% csrf_token %}
      <!-- -------------------------------------------------- -->
      <!-- 入力フォーム                                       -->
      <!-- -------------------------------------------------- -->
      <div class="modal js-modal">
        <div class="modal_bg js-modal-close"></div>
        <div class="modal_content">

          <div class="reserve_input"><!-- reserve_input start -->
            <!-- 予約ID -->
            <div class="reserve_input_div">
              {{ form.reserv_id }}
              <label>{{ form.reserv_id.label }}</label>
                <span class="focus_line"></span>
              </div>

              <!-- 会議室ID -->
              <div class="reserve_input_div">
                {{ form.room_id }}
                <label>{{ form.room_id.label }}</label>
                <span class="focus_line"></span>
              </div>

              <!-- 利用者 -->
              <div class="reserve_input_div">
                {{ form.reserv_name }}
                <label>{{ form.reserv_name.label }}</label>
                <span class="focus_line"></span>
              </div>

              <!-- 開始日時 -->
              <div class="reserve_input_div">
                {{ form.start_date_time }}
                <label>{{ form.start_date_time.label }}</label>
                <span class="focus_line"></span>
              </div>

              <!-- 終了日時 -->
              <div class="reserve_input_div">
                {{ form.end_date_time }}
                <label>{{ form.end_date_time.label }}</label>
                <span class="focus_line"></span>
              </div>

              <!-- ボタン関連 -->
              <div class="reserve_div_button">
                 <div id="input_button" class="reserve_input_div_button">
                  <input type="submit" class="submit_insert" name="action" value="登 録">
                </div>

                <div id="update_button" class="reserve_input_div_button">
                  <input type="submit" class="submit_insert" name="action" value="更 新">
                </div>

                <div id="delete_button" class="reserve_input_div_button">
                  <input type="submit" class="submit_insert" name="action" value="削 除">
                </div>
              </div>
          </div><!-- reserve_input end  -->
          <a class="js-modal-close" href="">閉じる</a>
        </div><!--modal_inner-->
      </div><!--modal-->
    </form>
  </body>
</html>
    

mrrs/forms.pyコーディング

フォームを修正します。

    
from django import forms

class reserv_room(forms.Form):
    """
    reserv_roomのフォーム.

    """
    # 予約ID
    reserv_id = forms.CharField(
        label = 'ID',
        max_length = 20,
        required = True,
        widget = forms.TextInput(attrs={'class' : 'reserve_type_text'})
    )
    # 会議室ID
    room_id = forms.CharField(
        label = '会議室ID',
        max_length = 20,
        required = True,
        widget = forms.TextInput(attrs={'class' : 'reserve_type_text'})
    )
    # 利用者
    reserv_name = forms.CharField(
        label = '利用者',
        max_length = 20,
        required = True,
        widget = forms.TextInput(attrs={'class' : 'reserve_type_text'})
    )
    # 開始日時
    start_date_time = forms.CharField(
        label = '開始日時',
        max_length = 20,
        required = True,
        widget = forms.TextInput(attrs={'class' : 'reserve_type_text'})
    )
    # 終了日時
    end_date_time = forms.CharField(
        label = '終了日時',
        max_length = 20,
        required = True,
        widget = forms.TextInput(attrs={'class' : 'reserve_type_text'})
    )
    

formにhtmlのデザイン属性のclassを追加しています

mrrs/views.pyコーディング

更新、削除のコーディングを行います。

    
from django.http.response import HttpResponse
from django.shortcuts import render
from .models import room_reservation

from . import forms

def mrrs(request):
    """
    会議室予約システム画面の関数
    """
    # リクエストがPOST形式の場合 データーベースに会議室予約システムの情報を登録する.
    if request.method == "POST":

        # 予約ID
        reserv_id = request.POST.get('reserv_id')
        # 会議室ID
        room_id = request.POST.get('room_id')
        # 利用者
        reserv_name = request.POST.get('reserv_name')
        # 開始日時
        start_date_time = request.POST.get('start_date_time')
        # 終了日時
        end_date_time = request.POST.get('end_date_time')  

        if '登 録' in request.POST.get('action'): 
            # リクエストパラメーターをデーターモデルに当て込みます.
            data_object = room_reservation(
                id=reserv_id, 
                room_id=room_id, 
                user=reserv_name, 
                start_date_time=start_date_time, 
                end_date_time=end_date_time, 
                del_flg=0)
            # データーを登録する.
            data_object.save()
        
        if '削 除' in request.POST.get('action'): 
            # リクエストパラメーターをデーターモデルに当て込みます.
            data_object = room_reservation(
                id=reserv_id, 
                room_id=room_id, 
                user=reserv_name, 
                start_date_time=start_date_time, 
                end_date_time=end_date_time, 
                del_flg=0)
            # データーを削除する.
            data_object.delete()

        if '更 新' in request.POST.get('action'): 
            # リクエストパラメーターをデーターモデルに当て込みます.
            data_object = room_reservation(
                id=reserv_id, 
                room_id=room_id, 
                user=reserv_name, 
                start_date_time=start_date_time, 
                end_date_time=end_date_time, 
                del_flg=1)
            # データーを更新する.
            data_object.save()


    # データーモデルからデーターを取得する.
    reserv_data = room_reservation.objects.all()
    # フォームオブジェクトを取得する.
    form = forms.reserv_room(request.GET or None)
    # テンプレートに渡す値を設定する
    display = {
        'form': form,
        'reserv_data' : reserv_data,
    }

    return render(request, 'resurv.html', display)
    

まとめ

サーバーを起動します。

    
python manage.py runserver
    

urlを入力します。

http://127.0.0.1:8000/mrrs/


コメント

0 件のコメント:

コメントを投稿

コメントをお待ちしています。