[Learn in 5 minutes] Code a web application with Flask (part 3)

Enrique Corona
3 min readMar 21, 2023

Now that we have the APIs and the main UI for our book management web application we can create the pages for adding, updating and deleting books.

First let’s write the UI for adding a new book, let’s create a template in intemplates/add.html with a web form for the name and author of the book and Javascript code to invoke the API to add a book (POST /book ).

<!doctype html>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js">
</script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$('#submit').click(function() {
$.ajax({
type: 'POST',
url: '/books',
contentType: 'application/json',
data: JSON.stringify({
'name': $('#name').val(),
'author': $('#author').val()
})
}).done(function() {
$('#result').text('Book added!');
})
});
});
</script>
<title>Add a new book</title>
<h2>Add a new book</h2>
<table id="book">
<tr>
<th>Name</th>
<td><input id="name" type="text"/></td>
</tr>
<tr>
<th>Author</th>
<td><input id="author" type="text"/></td>
</tr>
<tr>
<th></th>
<td><input id="submit" type="button" value="Add"/></td>
</tr>
<tr>
<th colspan="2"><span id="result"></span></th>
</tr>
</table>
<a href="/frontend/list">Go back</a>

Note how we are updating the <span> with id result after the book is added, and also note how we are adding a link to return to the main list of books that we defined in the previous article.

After adding a new book

If you remember, in the previous article we used a link to/frontend/edit?book_id=<book_id> in the main list of books to edit an existing book, first let’s define that endpoint.

@app.route('/frontend/edit', methods=['GET'])
def uiEditBook():
return render_template('edit.html', book=getBook(request.args.get('book_id')));

Note how we are passing to the template edit.html the book loaded with the id defined in the query param book_id , now let’s define templates/edit.html in a very similar way to add.html except that in this case we’ll pre-load the web form with the existing values of the book and we’ll call the API PUT /books to update the book.

<!doctype html>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js">
</script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$('#submit').click(function() {
$.ajax({
type: 'PUT',
url: '/books/{{book.uuid}}',
contentType: 'application/json',
data: JSON.stringify({
'uuid': '{{book.uuid}}',
'name': $('#name').val(),
'author': $('#author').val()
})
}).done(function() {
$('#result').text('Book updated!');
})
});
});
</script>
<title>Update {{book.name}}</title>
<h2>Update a book</h2>
<table id="book">
<tr>
<th>Name</th>
<td><input id="name" type="text" value="{{book.name}}"/></td>
</tr>
<tr>
<th>Author</th>
<td><input id="author" type="text" value="{{book.author}}"/></td>
</tr>
<tr>
<th></th>
<td><input id="submit" type="button" value="Update"/></td>
</tr>
<tr>
<th colspan="2"><span id="result"></span></th>
</tr>
</table>
<a href="/frontend/list">Go back</a>
After updating the new book

Finally to delete a book let’s define the endpoint /frontend/delete we are using in the list of books.

@app.route('/frontend/delete', methods=['GET'])
def uiDeleteBook():
deleteBook(request.args.get('book_id'))
return uiListBooks()

Similar to /frontend/edit we are using the query parameter book_id, but in this case to delete directly the book instead of calling the API DELETE /books, this way we don’t need to define any additional template.

Before deleting the new book
After deleting the new book

Note that in this endpoint we are returning uiListBooks() which will render the list of books (without the book we just deleted).

Now you have a toy application working end to end, I included some common best practices that are used when defining REST APIs and also I didn’t include any UI and API validations and error handling so feel free to include them when trying out this code.

--

--