安価なWeb開発勉強環境の構築③

**前回までの内容**
[安価なWeb開発勉強環境の構築①](https://qiita.com/MasahiroShouya/items/6cd832c6eee0645055c3)
　こちらでWebサーバをセットアップしています
[安価なWeb開発勉強環境の構築②](https://qiita.com/MasahiroShouya/items/691601d10a85f4bae371)
　こちらでPostgresをセットアップしています

**今回の内容**
これまでの環境を利用して、開発環境を準備します
以下のように``ＭＶＣ``を考えてみます
　``M``：sqlalchemyのDB定義をパッケージ化して利用します
　``V``：jinjaでHTMLの見た目を整地します
　``C``：Blueprintで制御を行います
 一人で抱える程度のWebサイトであれば、特に気にする必要はないかと思います。
 複数名で開発する規模のWebサイトであれば、開発ルールは重要です。
 保守性の高いシステムを目指していきましょう。

**フォルダ構成**
```diff_conf:フォルダ構成（/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
```
 **各ファイルの記述**
```diff_python:app.wsgi
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, "/flask/test1")
from app import app as application
```
```diff_python: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()
```
```diff_javascript:app/static/js/base.js
function showMessage() {
  alert("ボタンがクリックされました！");
}
async function ajaxJump(alink, id) {
    $.ajax({
        url: alink,
        success: function(data) {
            $("#" + id).html(data);
        }
    });
}
```
```diff_css:app/static/css/base.css
body {
  background-color: #F0F8FF;
}
```
```diff_css:app/static/css/menu1.css
ol li {
  font-size: 1.5em;
}
```
```diff_python:app/config.py
# データベース接続文字列
DATABASE_URI = "postgresql://flask1:パスワード@localhost:5432/flask1"
# デフォルトのタイムゾーン
DEFAULT_TIMEZONE = "Asia/Tokyo"
```
```diff_python: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))
```
```diff_html: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>
```
```diff_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 %}
```
```diff_python: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)
```
```diff_html: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すると一覧が表示されれば完了です。

多くのサンプルプログラムを載せていますが、、、
「開発ルール」と言っておきながら、プログラムのコメントが無く、
 未熟さ多々ですが、スタートに必要な開発ネタぐらいにはなるかと思います。