Vue.js:Python BottleからForm入力をJsonでPostしサーバから受信したJsonデータを表示する。
2020年3月13日Python Bottle Framework, トピックス

最近はJQueryからVue.jsの切り替えが多くなってきている。更に入力フォームもJSONでサーバにPOSTしてレスポンスをサーバから返ってきたJsonで表示を更新するケースが主流になってきています。WORDPRESSもAPI対応しているし、シングルページアプリケーション(SPA)なども流行りの中、このようなやり方をPython Bottleフレームワークで作る場合の基本的な実装方法について今回は掲載しようと思います。(このような仕組みを一般的にヘッドレスという。画面遷移させずにダイナミックにページを変化(更新)させるという意味合いでヘッドレスなのでしょう。ajaxでは定番ですが設計思想という観点でこのようなヘッドレスという用語ができたのだと思います。)やりようによってはテンプレートの開発・編集が単純化するためアプリケーションサーバをJSONのAPIサーバとして位置づけることもでき開発が非常にシンプルになります。
プロジェクトの作成
ファイルは全部で3種類用意します。WEBアプリのjsonform.py、Vueスクリプトのstatic/app.js、表示テンプレートのviews/form.htmlになります。予めフォルダーを作成し準備しましょう。
| 
					 1 2 3 4  | 
						$ mkdir myproj $ cd myproj   <---- jsonform.pyの設置場所 $ mkdir  views <--- form.htmlの設置場所 $ mkdir  static  <---app.jsの設置場所  | 
					
入力フォームの用意
formはシンプルに設置し後はVueの方に任せます。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32  | 
						<!DOCTYPE html> <html lang="ja"> <head>     <meta charset="UTF-8">     <title>Vue throw Json with POST to Python Server when Form Data submitting</title> </head> <body>     <h1>Test Form Monitor with Vue.JS</h1> <div id="app">     <h1>入力フォーム</h1>     <hr> <form v-on:submit.prevent="submit">        名前:<input v-model="info.name"><br>        ニックネーム: <input v-model="info.nickname"><br>        性別: <input v-model="info.gender"><br>         <input type="submit" value="submit"> </form>     <hr>    <div v-if="visual">        <h2>Json POST Response Results</h2>         <ul>           <li v-for="(item,index) in results"> [[index]] : [[ item ]] </li>         </ul>    </div> </div>     <script src="https://unpkg.com/axios/dist/axios.min.js"></script>     <script src="https://unpkg.com/vue"></script>     <script src="https://unpkg.com/jquery"></script>     <script src="/static/app.js"> </script> </body> </html>  | 
					
pythonアプリの用意。
上記の コンテンツを表示するため、bottleを使ったpythonWEBアプリを用意します。細かい解説は省略します。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  | 
						from bottle import Bottle,route,template,static_file,request,HTTPResponse import simplejson as json app = Bottle() app.config['autojson'] = True @app.route('/static/<filename>') def static(filename):     return static_file(filename, root='./static') #JSONで送出する入力フォーム @app.route('/data/json-form', method='GET') def index():      username = "Json Test Form"      return template('form',username = username) #JSONで受け取りJSONでレスポンスを返す。JSONエコー出力 @app.route('/data/json-get', method='POST') def somethingjson():     data = request.json     #CORS対策     header = {           'Content-Type': 'application/json',           'Access-Control-Allow-Origin': '*',           'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization'     }     ret = HTTPResponse(status=200, body=json.dumps(data,ensure_ascii=False, encoding='utf8', indent=2), headers=header)     return ret if __name__ == '__main__':      app.run(host="0.0.0.0",port="3000",debug=True)  | 
					
CORS(Cross-Origin Resource Sharing)によるクロスドメイン通信は今どきSSL通信でJSONのやり取りするなら、サーバ側のJSONを吐くアプリケーションでは必須でやらないと失敗します。予め調べて置いてくださいね。クライアント側はブラウザーの種類とバージョンによりけり。
FormをJsonで送出するVueのスクリプト
HTMLの表示制御を行うVueスクリプト。フォームの入力内容をsubmitボタンの押下をスキャンしjsonでデータをサーバに送出します。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26  | 
						var app = new Vue({     el: '#app',     delimiters: ['[[', ']]'],     data: {         visual: false,         results: [],         info: {             name: '',             nickname: '',             gender: ''         }     },     methods: {         submit: function() {            axios.post('/data/json-get', this.info)                .then(response => {                    this.results = response.data;                    this.visual = true;            })                .catch(error => {                    console.log(error);                })         }     } });  | 
					
アプリの起動
| 
					 1  | 
						$ python3  jsonform.py  | 
					
起動したらブラウザーからアクセスしてみましょう。URLは適当なサーバへインストールしてドメインを割り振っても良いですし、Linuxのローカルホストマシンでやっても良いと思います。例えばこんな感じで「http://localhost:3000/data/json-form」を入力します。
入力フォーム投稿前
入力フォーム投稿後の表示
curlでコンソールからテストする場合
 
		
		
			
			
			
			
				
					
				
					1
				 
						$ curl -H 'Content-Type:application/json' -d '{"name":"安倍晋三","nickname":"しんちゃん","gender":"男"}' http://localhost:3000/data/json-get 
					 
				
			
		
 
curlでコンソールからテストする場合
| 
					 1  | 
						$ curl -H 'Content-Type:application/json' -d '{"name":"安倍晋三","nickname":"しんちゃん","gender":"男"}' http://localhost:3000/data/json-get  | 
					
	