Bottle micro web services framework 7 : Bucket List App III - Editing
List of Bottle Micro Web Services Tutorials
- Introduction
- Static files
- Template
- json
- Bucket List App I - sqlite, route, and template
- Bucket List App II - get & post
- Bucket List App III - Editing
- Bucket List App IV - route validation, regex, and static_file
- Bucket List App V - json
- json to html table
- Forms - Get & Post
- Forms - Get & Post with editable and checkbox table cells
Continued from the previous chapter, Bucket List App II, in this chapter, we'll cover the key features of Bottle framework by upgrading the Buck list app we made.
The list of wishes is shown below:
Now we want to use bottle's 'dynamic routes' to enable editing of existing items. The basic statement for a dynamic route looks like this:
@route('/route/:something')
The colon(:) tells Bottle to accept for :something, and the value of something will be passed to the function assigned to that route so that the data can be processed within the function.
For our Bucket list, we will create a route @route('/edit/:wishId), where wishId is the id of the item to edit.
The code (bucket.py) should look like this:
import sqlite3 from bottle import route, run, template, request HOST = 'localhost' PORT = 8080 @route('/bucket') def bucket_list(): conn = sqlite3.connect('bucket.db') c = conn.cursor() c.execute("SELECT id, wish, status FROM bucket WHERE status LIKE '0' OR '1'") result = c.fetchall() c.close() return template('wish_table', rows=result) @route('/new', method='GET') def new_item(): if request.GET.get('save','').strip(): new = request.GET.get('wish', '').strip() conn = sqlite3.connect('bucket.db') c = conn.cursor() c.execute("INSERT INTO bucket (wish,status) VALUES (?,?)", (new,1)) new_id = c.lastrowid conn.commit() c.close() return '<p>The new wish was inserted into the database, the ID is %s</p>' % new_id else: return template('new_wish.tpl') @route('/edit/:wishId', method='GET') def edit_item(wishId): if request.GET.get('save','').strip(): edit = request.GET.get('wish','').strip() status = request.GET.get('status','').strip() if status == 'open': status = 1 else: status = 0 conn = sqlite3.connect('bucket.db') c = conn.cursor() c.execute("UPDATE bucket SET wish = ?, status = ? WHERE id LIKE ?", (edit, status, wishId)) conn.commit() return '<p>The item number %s was successfully updated</p>' % wishId else: conn = sqlite3.connect('bucket.db') c = conn.cursor() c.execute("SELECT wish FROM bucket WHERE id LIKE ?", str(wishId)) cur_data = c.fetchone() return template('edit_wish', old=cur_data, wishId=wishId) run(host=HOST, port=PORT, debug=True)
Here we're using the dynamic route :wishId, which passes the number to the corresponding function. As we can see, wishId is used within the function to access the right row of data within the database.
The template edit_wish.tpl called within the function looks like this::
%#template for editing a wish %#the template expects to receive a value for "wishId" as well a "old", the text of the selected bucket item <p>Edit the wish with ID = {{wishId}}</p> <form action="/edit/{{wishId}}" method="get"> <input type="text" name="wish" value="{{old[0]}}" size="70" maxlength="70"> <select name="status"> <option>open</option> <option>closed</option> </select> <br/> <input type="submit" name="save" value="Save the wish""> </form>
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization