9
12

More than 3 years have passed since last update.

【Python】Flaskで入退室管理システムを作ってみた

Last updated at Posted at 2020-12-13

はじめに

例のウイルスの影響で研究室にいつだれが入退室したかの記録が必要になり,QRコードで入退室処理できるシステムを作成しました.
研究室の扉などに貼ってある在室表もオンライン化してみました

前提条件

  • 研究室などで共通のネットワークを使用していること
  • 常時稼働できるPCがあること

開発環境

Windows 10
Anaconda 4.8.5
Python 3.7.4
Flask 1.1.1

インストール

Flaskのインストール
C:\Users\foo>pip install Flask

ディレクトリ構成

PythonApp
 ├static/
 ├templates/
 │  ├index.html
 │  ├in.html
 │  └out.html
 ├log.txt
 └app.py

フロントエンド

メイン画面

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>入退室管理システム</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel= "stylesheet" type= "text/css" href= "https://use.fontawesome.com/releases/v5.6.1/css/all.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" 
    integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
    <SCRIPT LANGUAGE="JavaScript">
      setTimeout("location.reload()",1000*5);
    </SCRIPT>
</head>
<body>
    <header>
    </header>
    <div class="container">
        <div class="row align-items-center" style="height:3rem;">
        </div>
        <div class="border-bottom mx-auto" style="max-width: 25rem;">
          <div class="text-center"><h5>現在の入室人数</h5>
          </div>
        </div>
        <div class="list-inline text-center">
          <i class="list-inline-item fas fa-users fa-4x"></i>
          <h1 class="list-inline-item text-danger display-1 ">{{li_all}}</h1>
          <h5 class="list-inline-item text-muted small"></h5>
        </div>
        <div class="mx-auto" style="width: 500px;">
                <h3>
                {% for i in li %}
                <li>{{ i }}</li>
                {% endfor %}
                </h3>
        </div>
    </div>
</body>
</html>

入室画面

in.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>入室画面</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel= "stylesheet" type= "text/css" href= "https://use.fontawesome.com/releases/v5.6.1/css/all.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" 
    integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</head>
<body>
    <header>
    </header>
    <div class="container">
        <div class="row align-items-center" style="height:3rem;">
        </div>
        <div class="text-center">
            <h4>入室画面</h4>
            <form action="/in" method="POST" enctype="multipart/form-data">
                <div>
                    <label for="name">名前:</label>
                    <input type="text" id="name" name="name" placeholder="名前">
                    <input type="submit" value="入室">
                </div>
            </form>
        </div>
    </div>

</body>
</html>

退室画面

out.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>退室画面</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel= "stylesheet" type= "text/css" href= "https://use.fontawesome.com/releases/v5.6.1/css/all.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" 
    integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</head>
<body>
    <header>
    </header>
    <div class="container">
        <div class="row align-items-center" style="height:3rem;">
        </div>
            <div class="text-center">
            <h4>退室画面</h4>
            <form action="/out" method="POST">
                <select name="name">
                    {% for name in li %}
                        <option value="{{ name }}">{{ name }}</option>
                    {% endfor %}
                </select>
                <button type="submit">退室</button>
            </form>
        </div>
    </div>
</body>
</html>

バックエンド

app.py
import os
import datetime
import itertools
from flask import Flask, request, redirect, url_for, render_template, flash

app = Flask(__name__)

name_list = []

@app.route('/')
def index():
    li_all = len(name_list)
    return render_template("index.html", li = name_list, li_all = li_all)

@app.route('/in')
def enter_get():
    return render_template("in.html")

@app.route('/in', methods=['POST'])
def enter_post():
    name = request.form['name']
    name_list.append(name)
    f = open('log.txt', 'a')
    dt_now = datetime.datetime.now()
    datalist = [name,',', str(dt_now),',', 'Enter the room\n']
    f.writelines(datalist)
    f.close()
    return redirect(url_for('index'))

@app.route('/out')
def out_get():
    if len(name_list) == 0:
        return redirect(url_for('index'))
    return render_template("out.html", li=name_list)

@app.route('/out', methods=['POST'])
def out_post():
    name = request.form['name']
    name_list.remove(name)
    f = open('log.txt', 'a')
    dt_now = datetime.datetime.now()
    datalist = [name,',', str(dt_now),',', 'Leave the room\n']
    f.writelines(datalist)
    f.close()
    return redirect(url_for('index'))

if __name__ == "__main__":
    app.run(host ='0.0.0.0',port = 8080, threaded=True, debug=True)

入退室した名前・時間をlog.txtに書き込みます.

起動

サーバーの起動
C:\Users\foo\PythonApp>python app.py

実行したら
https://localhost:8080 にアクセスしてみてください.
メイン画面が表示されているはずです.

QRコードの生成

QRコード生成サイトなどで作成してください.
・入室用

https://あなたのIPアドレス:8080/in

・退室用

https://あなたのIPアドレス:8080/out

・表示用

https://あなたのIPアドレス:8080/

おわりに

おわりです.

9
12
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
9
12