稼働中

(v_16)PythonのフレームワークBottleを試す(2)

Bottleで始めるWEBアプリ

前回の続きです。ブラウザで名前と年齢のデータベースからデータ一覧を表示、新規登録、「変更、削除」の操作を行います。
bottle、sqlite3を使います。
各動作を個別に作成した後でまとめました。※今回は④~⑤を記載して全体をまとめます。
※他の使用ファイルも「bottle.py」と同じフォルダに入れます。
①名前と年齢のデータベース作成 items.db
②データ表示 /list list_tmp2.tpl
③新規登録 /add add_tmp.tpl
④削除 /dell/id
⑤変更 /mod/id mod_tmp3.tpl

削除 /dell/id

「http://localhost:8080/dell/id」でデータを削除します。
データ表示ページのテンプレートlist_tmp3.tplでは、
<td><a href=”/del/{{item[‘id’]}}”>削除</a></td>
でリンクされていますが、ここでは使いません。


スクリプト web_del_01b.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from bottle import route, run, redirect
import sqlite3
# delete 削除
@route('/del/')
def del_item(item_id):
    con=sqlite3.connect('items.db')
    cur=con.cursor()
    #
    cur.execute("DELETE FROM items WHERE id =?", (item_id,))
    con.commit()
    con.close()
    
    return f'DELETE id={item_id}'
    #処理後に一覧画面に戻す
    #return redirect('/list')

run(host='localhost', port=8080, debug=True)

部分説明
「http://localhost:8080/del/id」で指定したidの登録が削除されます。

SQL文”DELETE FROM items WHERE id =?”で削除します。
削除後、削除したid値を表示します。
実使用ではデータ表示ページに戻すので、return redirect(‘/list’)にします。
実行結果
削除の例としてid=4を削除します。「http://localhost:8080/del/4」
削除後の表示
データ表示ページで確認するとid=4の削除が確認できます。
データ一覧表示ページ

変更 /mod/id

変更のページ「http://localhost:8080/mod/id」でデータを変更できるようにします。
Name、Ageの変更にテンプレートにmod_tmp3.tplを使っています。
中身は前回の記事内の新規登録とほとんど同じです。
id=2を変更する場合は、http://localhost:8080/mod/2になります。
データ変更ページ


テンプレート  mod_tmp3.tpl
<!DOCTYPE html>
<html>
<h3>Modify item name</h3>
<form method='POST'>
<input type='text' name='item_name' placeholder='Name'/>
<input type='text' name='item_age' placeholder='Age'/>
<input type='submit' value='変更'/>
</form>
</html>

スクリプト   web_mod_01b.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from bottle import route, run, template, request, redirect
import sqlite3
# modify 変更
@route('/mod/',method=['GET','POST'])
def mod_item(item_id):
    #item_name=[]
    if request.method=='POST':
        item_name=request.POST.getunicode('item_name')
        item_age=request.POST.getunicode('item_age')

        con=sqlite3.connect('items.db')
        cur=con.cursor()      
        cur.execute("UPDATE items SET name=? WHERE id =?", (item_name,item_id))
        cur.execute("UPDATE items SET age=? WHERE id =?", (item_age,item_id))
        
        con.commit()
        con.close()
        return f'UPDATE id={item_id}, name={item_name}, age={item_age}'
        #処理後に一覧画面に戻す
        #return redirect('/list')
    else:
        return template('mod_tmp3')

run(host='localhost', port=8080, debug=True)

部分説明
「http://localhost:8080/mod/id」で指定したidのデータ変更ができます。
SQL文”UPDATE items SET name=? WHERE id =?”で変更します。
変更後、変更したidのデータを表示します。
実使用ではデータ表示ページに戻すので、return redirect(‘/list’)にします。

実行結果
http://localhost:8080/mod/2、id=2をyamashita、34で変更してみました。
データ変更後の表示
データ表示ページで確認するとid=2の変更が確認できます。
変更後のデータ一覧ページ

全整理

データ表示(/list)、新規登録(/add)、削除(/dell/id)、変更(/mod/id)を整理してまとめいます。先に示したテンプレートlist_tmp3.tpl、add_tmp3.tpl、mod_tmp3.tplは変更ありません。
(/)でもデータ表示、登録、変更、削除後はデータ表示ページに戻るようにredirectに変更しています。


全整理後のスクリプト web_app_02b.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from bottle import route, run, template, request, redirect
import sqlite3
#database
con=sqlite3.connect('items.db')
cur=con.cursor()
#items.dbが無ければ作成
cur.execute('CREATE TABLE IF NOT EXISTS items(id,name,age)')
# 確定
con.commit()
con.close()

#データ一覧表示 /list
@route('/')
@route('/list')
def db_list():
    con=sqlite3.connect('items.db')
    cur=con.cursor()
    #SQL文 SELECT ASC 昇順 DESC 降順
    c=cur.execute("SELECT * FROM items ORDER BY id ASC")
    
    item_list=[]
    for row in c.fetchall():
        item_list.append({"id":row[0],"name":row[1],"age":row[2]})
    con.close()
    
    #list_tmp3.tpl に渡す変数data
    return template('list_tmp3',data=item_list)

# 新規登録 /add 
@route('/add',method=['GET','POST'])
def add_item():
    if request.method=='POST':
        item_name=request.POST.getunicode('item_name')
        item_age=request.POST.getunicode('item_age')
        
        con=sqlite3.connect('items.db')
        cur=con.cursor()

        #max ID SQL文 SELECT        
        c=cur.execute('SELECT max(id) FROM items')
        max_id=c.fetchone()[0]
        new_id=max_id+1
        #new_id=cur.execute('SELECT max(id)+1 FROM items').fetchone()[0]
        # table が空の場合にid=1を設定する
        if new_id==None:
            new_id=1
        #SQL文 INSERT     
        cur.execute('INSERT INTO items VALUES(?,?,?)',(new_id,item_name,item_age))
        con.commit()
        con.close
        
        #return f'SUCCESS id={new_id}, name={item_name}, age={item_age}'        
        #redirect list-page 
        return redirect('/list')
        
    else:
        #add-page
        return template('add_tmp3')

# delete 削除 /del/id
@route('/del/')
def del_item(item_id):
    con=sqlite3.connect('items.db')
    cur=con.cursor()
    #SQL文 DELETE
    cur.execute("DELETE FROM items WHERE id =?", (item_id,))
    con.commit()
    con.close()
    
    #return f'DELETE id={item_id}'
    #処理後に一覧画面に戻す
    return redirect('/list')

# modify 変更 /mod/id
@route('/mod/',method=['GET','POST'])
def mod_item(item_id):
    #item_name=[]
    if request.method=='POST':
        item_name=request.POST.getunicode('item_name')
        item_age=request.POST.getunicode('item_age')
        
        con=sqlite3.connect('items.db')
        cur=con.cursor()
        #SQL文 UPDATE
        cur.execute("UPDATE items SET name=? WHERE id =?", (item_name,item_id))
        cur.execute("UPDATE items SET age=? WHERE id =?", (item_age,item_id))
        
        con.commit()
        con.close()
        #return f'UPDATE id={item_id}, name={item_name}, age={item_age}'
        #処理後に一覧画面に戻す
        return redirect('/list')
    else:
        return template('mod_tmp3')

run(host='localhost', port=8080, debug=True)

実行結果
okada、42を追加した状態の結果です。削除、変更の動作も問題なさそうでした。
操作後のデータリストページ

まとめ

bottlとsqlite3を使って、名前と年齢のデータベースからデータの削除、変更を追加しました。
WEBページで一覧表示と新規登録、削除、変更が可能に全体を整理ました。
bottlとsqlite3の簡単な動作が確認できたと思います。