Pythonフレームワーク「Flask」でWijmoを使う

以前公開した記事では、PythonのWebアプリケーションフレームワーク「Flask」の導入方法、および簡単なWeb APIを作成する方法をご紹介しました。

今回は弊社が提供するJavaScript開発ライブラリ「Wijmo(ウィジモ)」のデータグリッドコントロール「FlexGrid」をFlaskに組み込んで、CRUD処理を行うアプリケーションを作成してみたいと思います。

開発環境

  • Python 3.11.0
  • Flask 2.2.2

アプリケーションの作成

まずはFlaskでアプリケーションを作成していきます。今回は前回作成したWeb APIの部分とは別にアプリケーションを作成して連携させてみたいと思います。flask-wijmo-appという名前で環境を作成します。

python -m venv flask-wijmo-app

「flask-wijmo-app」フォルダに移動し、仮想環境を有効化します。

cd flask-wijmo-app
Scripts\activate

さらに仮想環境が有効化されている状態で、以下のコマンドを実行してFlaskをインストールします。

pip install Flask

Wijmoの静的ファイルの配置

Flaskには「Jinja2」というテンプレートエンジンが用意されており、HTMLを動的に生成することができます。名前の由来は「template(テンプレート)」⇒「temple(お寺)」⇒「神社」から来ています。

「jinja2」は先ほどインストールしたFlaskと一緒にインストールされます。以下のコマンドで現在インストールされているパッケージの一覧を表示できます。

pip list
インストール済みパッケージのリスト

「Jinja2」では「templates」フォルダにHTMLなどのテンプレートファイルを配置し、「static」フォルダにJavaScriptやCSSなどの静的ファイルを配置します。

まずはアプリケーションのルート直下に「static」フォルダを作成し、さらにその配下に「js」フォルダと「css」フォルダも追加し、Wijmoのjsファイルとcssファイルを以下のように配置します。

  • static/css/wijmo.min.css
  • static/js/wijmo.min.js
  • static/js/wijmo.input.min.js
  • static/js/wijmo.grid.min.js
  • static/js/wijmo.grid.filter.min.js
  • static/js/cultures/wijmo.culture.ja.min.js

テンプレートファイルの作成

次に同じくアプリケーションのルート直下に「templates」フォルダを作成し「index.html」ファイルを追加し、Wijmoのライブラリの参照設定や、FlexGridの初期化処理、CRUD処理を行うための各種APIの呼び出し処理を記述します。

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <!-- styles -->
    <!-- Wijmoのスタイル(必須) -->
    <link href="/static/css/wijmo.min.css" rel="stylesheet" />

    <!-- Wijmoのコアモジュール(必須) -->
    <script src="/static/js/wijmo.min.js"></script>
    <!-- Wijmoコントロール(オプション。必要なコントロールを設定する) -->
    <script src="/static/js/wijmo.grid.min.js"></script>
    <script src="/static/js/wijmo.grid.filter.min.js"></script>
    <script src="/static/js/wijmo.input.min.js"></script>
    <!-- Wijmoカスタムカルチャー(オプション。任意のカルチャーを設定する) -->
    <script src="/static/js/wijmo.culture.ja.min.js"></script>

    <style>
        .grid {
            height: 250px;
        }
    </style>
</head>

<body>
    <div id="flexGrid"></div>
    <button id="btn">データを更新する</button>

    <script>
        const url = 'http://127.0.0.1:5001/order';
        
        var cv = new wijmo.collections.CollectionView(null, {
            trackChanges: true
        });

        var flexGrid = new wijmo.grid.FlexGrid('#flexGrid', {
            itemsSource: cv,
            allowAddNew: true,
            allowDelete: true,
            autoGenerateColumns: false,
            columns: [
                { binding: 'product', header: '商品名', width: 200 },
                { binding: 'date', header: '受注日', format: 'yyyy-mm-dd', },
                { binding: 'amount', header: '受注数', width: 80 },
            ]
        });

        // read
        wijmo.httpRequest(url, {
            success: function (xhr) {
                cv.sourceCollection = JSON.parse(xhr.responseText)
            },
            error: function (xhr) {
                window.alert('データを読み込めませんでした')
            }
        });

        document.getElementById('btn').addEventListener('click', function () {
            //update
            for (var i = 0; i < cv.itemsEdited.length; i++) {
                wijmo.httpRequest(url + '/' + cv.itemsEdited[i].id, {
                    method: 'PUT',
                    //requestHeaders: requestHeaders,
                    data: cv.itemsEdited[i],
                    
                    error: function (xhr) {
                        console.log(xhr)
                    }
                });
            }

            //create
            for (var i = 0; i < cv.itemsAdded.length; i++) {
              
                wijmo.httpRequest(url, {
                    method: 'POST',
                    data: cv.itemsAdded[i],
                    error: function (xhr) {
                        console.log(xhr)
                    }
                });
            }

            //delete
            for (var i = 0; i < cv.itemsRemoved.length; i++) {
                wijmo.httpRequest(url + '/' + cv.itemsRemoved[i].id, {
                    method: 'DELETE',
                    error: function (xhr) {
                        console.log(xhr)
                    }
                });
            }
        })
    </script>
</body>
</html>

起動ファイルの作成

最後にメインの起動ファイルを作成します。アプリケーションのルート直下に「app.py」を作成し、以下の内容を記述します。今回はブラウザから「http://127.0.0.1:5000/」にアクセスしたときに「index.html」のテンプレートを実行するように設定しています。

from flask import Flask
from flask import render_template

app = Flask(__name__)

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

最終的なフォルダ構成は以下の様になります。

アプリケーションのフォルダ構成

アプリケーションの実行

この時点で一度アプリケーションを起動してみます。以下のコマンドを実行してアプリケーションを起動します。

flask run

http://127.0.0.1:5000/」にアクセスすると、以下のようにブラウザ上に空の状態のFlexGridが表示できます。

空のFlexGrid

CRUD処理の実行

Web APIのCORSの設定

次にWeb APIと連携し、WijmoのFlexGrid上からCRUD処理を実行していきます。Web APIは前回作成したものを使用します。

今回はFlexGridを表示するアプリとAPIは別アプリになるので、異なるポートからAPIが呼び出せるようにCORSの設定を追加します。FlaskでのCORSの設定には「Flask-CORS」を使用します。

以下のコマンドを実行してFlask-CORSをインストールします。

pip install flask-cors

インストールが完了したら前回作成した「flask-api-app」の「__init__.py」を以下のように追記します。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from flask_cors import CORS

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///order.sqlite3'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config['JSON_AS_ASCII'] = False #日本語を利用

#SQLAlchemyでデータベース定義
db = SQLAlchemy(app)
ma = Marshmallow(app)
cors = CORS(app)

import src.db

最後に以下のコマンドを実行してAPIを起動します。この時、Wijmoを組み込んだアプリ側とポートが被らないように別のポート(5001)を指定して起動します。

flask run -p 5001

データの読み込み(READ)

APIを起動したら「flask-wijmo-app」も再度起動し、「http://127.0.0.1:5000/」にアクセスすると、ブラウザ上のFlexGridにデータが表示されます。

データの読み込み

データの登録(CREATE)

グリッドの一番下の行にデータを入力し、[更新]ボタンをクリックすると、データの登録ができます。

データの更新(UPDATE)

程追加したデータの一部を編集し、[更新]ボタンをクリックすると、データの更新ができます。

データの削除(DELETE)

先程追加したデータの行を選択後、Deleteキーで削除し、[更新]ボタンをクリックすると、データの削除ができます。

さいごに

以上がFlaskに「Wijmo」のデータグリッドコントロール「FlexGrid」を組み込んで、CRUD処理を実装する方法でした。WijmoにはFlexGrid以外にも高機能なUIコントロールが含まれていますので、気になった方はぜひ製品サイトもご覧ください。

製品サイトでは、Wijmoの機能を手軽に体験できるデモアプリケーションやトライアル版も公開しておりますので、こちらもご確認ください。

また、ご導入前の製品に関するご相談、ご導入後の各種サービスに関するご質問など、お気軽にお問合せください。

\  この記事をシェアする  /