0
0

More than 1 year has passed since last update.

40代おっさん面会予約アプリを作ってみる④

Last updated at Posted at 2022-11-22

本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

前回の記事

https://qiita.com/kou1121/items/bea7575176b07bd16bb9
https://qiita.com/kou1121/items/94ff8d65976dab98dfc8
https://qiita.com/kou1121/items/318fe6cc0e0564e533b4

ユーザー登録画面の作成

app.pyを作る

import streamlit as st
import random # ランダム値がほしいので
import datetime # 時刻を扱うため
import requests
import json

#  サイドバーを作って各ページを用意
page = st.sidebar.selectbox('ページを選択してください', ['ユーザー登録', '面会室登録', '面会予約'])

if page == 'ユーザー登録':

    st.title('登録画面')

    with st.form(key='user'):
        # user_id: int = random.randint(0, 10)
        username: str = st.text_input('ユーザー名', max_chars=12) # 12字しか入力できなくなる。
        data = {
            # 'user_id': user_id,
            'username': username
        }
        submit_button = st.form_submit_button(label='ユーザー登録') # form専用のボタン

    if submit_button: # ボタンが押されたされる処理
        st.write('## 送信データ') # デバック用
        st.write('## レスポンス結果')
        url = 'http://127.0.0.1:8000/users'
        res = requests.post(
            url,
            data=json.dumps(data)
        )
        if res.status_code == 200:
            st.success('ユーザー登録完了')
        st.write(res.status_code) # レスポンスのステータスコード
        st.json(res.json())

こちらで実行してみるとエラーが出てしまうので
usernameの値のみになってしまうので、前に作ったschemas.Userとデータの方が合わないので、そちらを直します。

schemas.pyを直します

import datetime
from pydantic import BaseModel, Field

class BookingCreate(BaseModel):
    user_id: int # ユーザーID usersテーブルと紐づけ
    room_id: int # 面会室ID roomsテーブルと紐づけ
    booked_num: int # 予約人数 面会室の定員まで
    start_datetime: datetime.datetime # 開始時刻
    end_datetime: datetime.datetime # 終了時刻

class Booking(BookingCreate):
    booking_id: int # 予約ID

    class Config:
        orm_mode = True # ormモデルに対応させる

class UserCreate(BaseModel):
    #  user_id: int は自動で生成されるのでいらない
    username: str = Field(max_length=12) # フォームから入力時に必要なため

class User(UserCreate): # UserCreateを継承 username: strいらない
    user_id: int # ユーザーID

    class Config:
        orm_mode = True # ormモデルに対応させる

class RoomCreate(BaseModel):
    room_name: str = Field(max_length=12) # 面会室名(12文字まで)
    capacity: int # 定員 各面会室ごとに定める

class Room(RoomCreate):
    room_id: int # 面会室ID

    class Config:
        orm_mode = True # ormモデルに対応させる

このように各クラスにCreate部分を作りました。
これはデータ登録時にいらないデータを省いてCreate側で受け取れるようにするためです。
次にこちらも変えます

main.py
のpost部分を変えます。

# Create
@app.post("/users", response_model=schemas.User)
async def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
    return crud.create_user(db=db, user=user)

@app.post("/rooms", response_model=schemas.Room)
async def create_room(room: schemas.RoomCreate, db: Session = Depends(get_db)):
    return crud.create_room(db=db, room=room)

@app.post("/bookings", response_model=schemas.Booking)
async def create_booking(booking: schemas.BookingCreate, db: Session = Depends(get_db)):
    return crud.create_booking(db=db, booking=booking)

schemas.UserCreateの型を受け取れるようにしています。
ただしreturnしているのはresponse_model=schemas.UserなのでUser型になっています。

面会室登録画面の作成

import streamlit as st
import datetime # 時刻を扱うため
import requests
import json
import pandas as pd

#  サイドバーを作って各ページを用意
page = st.sidebar.selectbox('ページを選択してください', ['ユーザー登録', '面会室登録', '面会予約'])

if page == 'ユーザー登録':

  # 上を参照

elif page == '面会室登録':
    st.title('面会室登録画面')

    with st.form(key='room'):
        # room_id: int = random.randint(0, 10)
        room_name: str = st.text_input('面会室名', max_chars=12) # 12字しか入力できなくなる。
        capacity: int = st.number_input('定員', step=1) # 定員 1刻みで入力
        data = {
            # 'room_id': room_id,
            'room_name': room_name,
            'capacity': capacity
        }
        submit_button = st.form_submit_button(label='面会室登録') # form専用のボタン

    if submit_button: # ボタンが押されたされる処理
        st.write('## レスポンス結果')
        url = 'http://127.0.0.1:8000/rooms'
        res = requests.post(
            url,
            data=json.dumps(data)
        )
        if res.status_code == 200:
            st.success('面会室登録完了')
        st.write(res.status_code) # レスポンスのステータスコード
        st.json(res.json())

面会室の予約画面の作成

ユーザー、面会室情報の取得

# ユーザー一覧を取得
    url_users = 'http://127.0.0.1:8000/users'
    res = requests.get(url_users)
    users = res.json() # usersのリストが返ってくる
    # ユーザー名をキー、ユーザーIDをバリュー
    users_dict = {}
    for user in users:
        users_dict[user['username']] = user['user_id']

    # 面会室一覧の取得
    url_rooms = 'http://127.0.0.1:8000/rooms'
    res = requests.get(url_rooms)
    rooms = res.json() 
    rooms_dict = {}
    for room in rooms:
        rooms_dict[room['room_name']] = {
            'room_id': room['room_id'],
            'capacity': room['capacity']
        }

予約フォームの作成

import streamlit as st
import datetime # 時刻を扱うため
import requests
import json
import pandas as pd

#  サイドバーを作って各ページを用意
page = st.sidebar.selectbox('ページを選択してください', ['ユーザー登録', '面会室登録', '面会予約'])

if page == 'ユーザー登録':

    # 上を参照

elif page == '面会室登録':
    
    # 上を参照

elif page == '面会予約':
    st.title('面会室予約画面')
    # ユーザー一覧を取得
    # 上を参照

    # 面会室一覧の取得
    # 上を参照

    st.warning('### 面会室一覧')
    df_rooms = pd.DataFrame(rooms)
    df_rooms.columns = ['面会室名', '定員', '会議室ID']
    st.table(df_rooms)
    
    with st.form(key='booking'):
        username: str = st.selectbox('予約者名', users_dict.keys()) # users_dict.keys()で名前を取ってこれる
        room_name: str = st.selectbox('面会室名', rooms_dict.keys()) # rooms_dict.keys()で面会室名を取ってこれる
        booked_num: int = st.number_input('予約人数', step=1, min_value=1) # 予約人数 1刻みで入力
        date = st.date_input('日付: ', min_value=datetime.date.today()) # 最小値(min)に今日(today)の日付を設定
        start_time = st.time_input('面会開始時刻: ', value=datetime.time(hour=9, minute=0))
        end_time = st.time_input('面会終了時刻: ', value=datetime.time(hour=20, minute=0))
        
        submit_button = st.form_submit_button(label='予約登録') # form専用のボタン

    if submit_button: # ボタンが押されたされる処理
        user_id: int = users_dict[username]
        room_id: int = rooms_dict[room_name]['room_id']
        capacity: int = rooms_dict[room_name]['capacity']

        data = {
            
            'user_id': user_id,
            'room_id': room_id,
            'booked_num': booked_num,
            'start_datetime': datetime.datetime( 
                year=date.year,
                month=date.month,
                day=date.day,
                hour=start_time.hour,
                minute=start_time.minute
            ).isoformat(), # str型でないとダメなため
            'end_datetime': datetime.datetime( 
                year=date.year,
                month=date.month,
                day=date.day,
                hour=end_time.hour,
                minute=end_time.minute
            ).isoformat()
            
        }
        # 定員以下の予約人数の場合
        if booked_num <= capacity:
            # 面会室予約
            url = 'http://127.0.0.1:8000/bookings'
            res = requests.post(
                url,
                data=json.dumps(data)
            )
            if res.status_code == 200:
                st.success('予約完了しました')
            st.json(res.json())

        else:
            st.error(f'{room_name}の定員は、{capacity}名です。')

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0