前回までの内容
安価なWeb開発勉強環境の構築①
こちらでWebサーバをセットアップしています
安価なWeb開発勉強環境の構築②
こちらでPostgresをセットアップしています
今回の内容
これまでの環境を利用して、開発環境を準備します
以下のようにMVC
を考えてみます
M
:sqlalchemyのDB定義をパッケージ化して利用します
V
:jinjaでHTMLの見た目を整地します
C
:Blueprintで制御を行います
一人で抱える程度のWebサイトであれば、特に気にする必要はないかと思います。
複数名で開発する規模のWebサイトであれば、開発ルールは重要です。
保守性の高いシステムを目指していきましょう。
フォルダ構成
フォルダ構成(/flask/test1)
├── app
│ ├── db (M:データベース関連処理をパッケージ化)
│ │ ├── __init__.py (空File)
│ │ └── dbtable.py (SQLAlchemy)
│ ├── static
│ │ ├── js
│ │ │ └── base.js (共通使用するJavaScript)
│ │ └── css
│ │ ├── base.css (画面全体に共通適用するStyle)
│ │ └── menu1.css (個々の画面で適用するStyle)
│ ├── templates
│ │ ├── base.html (ベースとなる画面のhtml)
│ │ └── menu1.html
│ ├── site (追加開発するのはコノ配下です)
│ │ └── list1
│ │ ├── templates
│ │ │ └── list1.html
│ │ └── subsite1.py
│ ├── __init__.py (初期起動画面の制御プログラム)
│ └── config.py (環境変数等の共通モジュール)
└── app.wsgi
各ファイルの記述
app.wsgi
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, "/flask/test1")
from app import app as application
app/__init__.py
from flask import Flask, Blueprint, render_template
app = Flask(__name__)
from app.site.list1 import subsite1
app.register_blueprint(subsite1.subsite, url_prefix='/sub1')
@app.route('/')
def index():
return render_template('menu1.html')
if __name__ == '__main__':
app.run()
app/static/js/base.js
function showMessage() {
alert("ボタンがクリックされました!");
}
async function ajaxJump(alink, id) {
$.ajax({
url: alink,
success: function(data) {
$("#" + id).html(data);
}
});
}
app/static/css/base.css
body {
background-color: #F0F8FF;
}
app/static/css/menu1.css
ol li {
font-size: 1.5em;
}
app/config.py
# データベース接続文字列
DATABASE_URI = "postgresql://flask1:パスワード@localhost:5432/flask1"
# デフォルトのタイムゾーン
DEFAULT_TIMEZONE = "Asia/Tokyo"
app/db/dbtable.py
from sqlalchemy import create_engine, Column, Integer, String, DateTime, Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from app.config import DATABASE_URI
engine = create_engine(DATABASE_URI)
Base = declarative_base()
Ses = sessionmaker(bind=engine)
class t_kbn(Base):
__tablename__ = 't_kbn'
zkbn = Column(String(5), primary_key=True)
znum1 = Column(Integer, primary_key=True)
znum2 = Column(Float)
zstdate = Column(DateTime)
zendate = Column(DateTime)
val1 = Column(String(50))
val2 = Column(String(50))
val3 = Column(String(50))
app/templates/base.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
{% block head %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/base.css') }}">
<script src="{{ url_for('static', filename='js/base.js') }}"></script>
{% endblock %}
</head>
<body>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
app/templates/menu1.html
{% extends "base.html" %}
{% block title %}menu1{% endblock %}
{% block head %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='css/menu1.css') }}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
{% endblock %}
{% block content %}
<table>
<tr><td valign="top">
<ol>
<li><a href="#" id="link">サブ画面表示</a></li>
<li><button onclick="showMessage()">メッセージを表示</button></li>
</ol>
</td>
<td valign="top"><div id="disMain">ここに表示</div></td></tr>
</table>
<script>
$(document).ready(function(){
$('#link').click(function(e){
e.preventDefault();
ajaxJump('/sub1', 'disMain');
});
});
</script>
{% endblock %}
app/site/list1/subsite1.py
from flask import Flask, Blueprint, render_template
from sqlalchemy.sql import operators
import app.db.dbtable
subsite = Flask(__name__)
subsite = Blueprint('subsite', __name__, template_folder="templates", static_folder="static")
@subsite.route('/')
def init():
with app.db.dbtable.Ses() as session:
tDt = session.query(app.db.dbtable.t_kbn).filter(operators.eq(app.db.dbtable.t_kbn.znum1, '1')).all()
return render_template('list.html', TableDT=tDt)
app/site/list1/templates/list.html
{% extends "base.html" %}
{% block title %}テスト{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
<table id="dTable" border=1>
<thead><th>区分</th><th>数字</th><th>日付</th></thead>
<tbody>
{% for dt in TableDT %}
<tr>
<td>{{ dt.zkbn }}</td>
<td>{{ dt.znum2 }}</td>
<td>{{ dt.zendate }}</td>
</tr>
{% endfor %}
</tbody></table>
{% endblock %}
全てのプログラムの準備が終わったら、
sudo systemctl restart apache2 (Webサービスの再起動)
後はテストです 「http://(RaspberryのIPアドレス):8080」
ボタンをClickするとメッセージが表示され、LinkをClickすると一覧が表示されれば完了です。
多くのサンプルプログラムを載せていますが、、、
「開発ルール」と言っておきながら、プログラムのコメントが無く、
未熟さ多々ですが、スタートに必要な開発ネタぐらいにはなるかと思います。