Insert or update items listed in an HTML page of a CherryPy web app
-
In this topic, we will see how to add a new item to a list of items or update an existing item in a list that we have in our database, from a web application developed using Python CherryPy framework.
Data can be stored in any kind of database or may be in a pre-defined list within the application (For CRUD samples utilizing different kinds of databases, you can refer the links on the right side of this page).
In this sample, we are going to work on a list of items that we are keeping in JSON format in a separate JSON file. We will add a new item to this list and also update an existing item. -
Python libraries required
Following python libraries are to be installed to run this sample.
CherryPy: An object-oriented web application framework to develop python based web application. Install this using the command pip install CherryPy
Jinja2: A template engine for Python. Jinja2 helps in serving the html to the user. Using this library along with CherryPy helps in faster code development.
-
Listing items
In order to work on insert and update, we should have a list of items displayed on our web page.
For this, copy code for three files items.json, listitems.html and list.py from Listing Items in CherryPy Web App and paste in your code folder.
items.json has the list of items that we are going to modify. -
HTML Code
Once the above set of code is copied, we can proceed with adding a new button in the List page to add new items. Also next to each row, we need to add a new link button, Edit to navigate to the Edit page.
Add a new link button in the listitems.html above the table.
<a class="btn btn-primary" href="openitemdetails/0">Add New Item</a>
Then modify the HTML table in the listitems.html as below to add the Edit button.
Copied<table class="table"> <thead> <tr> <th scope="col">Id</th> <th scope="col">Name</th> <th scope="col">Age</th> <th scope="col">Edit</th> </tr> </thead> <tbody> {% for emp in emps %} <tr> <td>{{ emp.id }}</th> <td>{{ emp.name }}</td> <td>{{ emp.age }}</td> <td><a href='openitemdetails/{{ emp.id }}'>Edit</a></td> </tr> {% endfor %} </tbody> </table>
Now add the new html file, additem.html and place the below code.
This page contains text box controls to enter/update the details. Note that we have provided the name and value properties for each of the text boxes. name property is used to access the control by name and value property is used to do the two way binding of the corresponding controls' data.
Copied<!DOCTYPE html> <html lang="en-US" dir="ltr"> <head> <title>Details</title> <link rel="stylesheet" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" > <script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" > </script> </head> <body> <h2>Details</h2> <form action="../savedetails" method = "POST"> <div class="form-group row"> <label for="id">Id</label> <input type="text" class="form-control" name="id" value="{{emp.id}}"> </div> <div class="form-group row"> <label for="name">Name</label> <input type="text" class="form-control" name="name" value="{{emp.name}}"> </div> <div class="form-group row"> <label for="age">Year</label> <input type="text" class="form-control" name="age" value="{{emp.age}}"> </div> <button type="btnAdd" class="btn btn-primary">Submit</button> <a href="/" class="btn btn-primary">Cancel</a> </form> </body>
-
Python Code
Copy the below code and paste it after index() method, to add two more route methods, openitemdetails() and savedetails() in list.py to handle routing to the Details page and saving the data (Double check the pasted contents are properly intended).
Add button in the list page calls openitemdetails route with ID as 0. So Details page opens in Create mode with empty text boxes.
Edit link next to each row also calls openitemdetails route, but passes ID number to the Details page. So the details of the selected item is fetched from the JSON file and bind to the corresponding text boxes in the HTML page.savedetails route is called on Submit button click. If the entered ID number doesn't exist, new item gets added. Otherwise, existing record is updated.
Copied@cherrypy.expose def openitemdetails(self, id=0): templenv = Environment(loader=FileSystemLoader(os.getcwd())) if int(id) == 0: return templenv.get_template('additem.html').render(emp=[]) else: with open(jsnfile) as b: emps = json.load(b) emp = [x for x in emps if x['id'] == id][0] return templenv.get_template('additem.html').render(emp=emp) @cherrypy.expose def savedetails(self, id=0, name='', age=0): idexists = 0 with open(jsnfile) as b: emps = json.load(b) if(len([x for x in emps if x['id'] == id]) == 0): emps.append({"id": id, "name": name, "age": age}) else: for emp in emps: if(int(emp['id']) == int(id)): emp['name'] = name emp['age'] = age break with open(jsnfile, 'w') as bw: json.dump(emps, bw) raise cherrypy.HTTPRedirect("/")
-
Running this sample
From command prompt, navigate to code folder and execute command py list.py or python list.py
We will see the below message when execution starts without any issues.[08/Jun/2022:18:11:50] ENGINE Listening for SIGTERM. [08/Jun/2022:18:11:50] ENGINE Bus STARTING CherryPy Checker: The Application mounted at '' has an empty config. [08/Jun/2022:18:11:50] ENGINE Started monitor thread 'Autoreloader'. [08/Jun/2022:18:11:50] ENGINE Serving on http://127.0.0.1:8080 [08/Jun/2022:18:11:50] ENGINE Bus STARTED
Copy the URL http://127.0.0.1:8080 to your browser and run to add/edit items.