Python: A shareable Todo lists/notes web app with web2py Part 2
Tips & Tricks 06-Feb-2019

Python: A shareable Todo lists/notes web app with web2py Part 2

In web2py, controllers are located in web2py_folder/applications/YOUR_APPLICATION_FOLDER/controllers. If your application is called bars and you create a new .py file called and add a function in it called view there, this would equal to the following path /bars/snickers/view.

We will create a controller called and add our functions/route methods there.

Here is how you can import modules in Python (we import the randint function from the random module).

from random import randint

In web2py, we use the following statement to connect to the MySQL database test with a user called root and empty password:

db = DAL(“mysql://root:@localhost/test”)

Then, we can use the define_table method to create a database table if it does not exist. For our notes app, we create a todos table with two strings columns – item and identifier.

db.define_table(‘todos’, Field(‘item’), Field(“identifier”))

We create our app’s landing route:

def index():

In it, we set the session cookie to expire after 5 years so that users’ note/todo lists will remain active for longer.

response.cookies[‘session_id_todo’][‘expires’] =   5* 12 * 30 * 24 * 3600

If the user has not been generated an identifier associated with his todo list, we create it. It is just a random string of letters and numbers.

f (not session.userIdentifier):

userIdentifier = “”

characters = [‘a’, ‘z’, ‘b’, ‘c’, ‘h’, ‘x’, ‘p’, ‘r’, ‘l’, ‘m’, ‘n’, “0”, “1”, “2”, “3”, “4”, “5”, “6”, “7” “8”,


for x in range(0, 10):

userIdentifier += characters[randint(0, len(characters) – 1)]

session.userIdentifier = userIdentifier

Then, if there are notes saved in the session we set userNotes (that variable will get sent to the view) to them. Notes saved in the session will consist of notes from some specific user identifier and not the user’s own identifier. Otherwise, we just get the user own note list from the database.

if (session.notes):

userNotes = session.notes


q = db.todos.identifier == session.userIdentifier

userNotes = db(q).select()

Finally, we return so that the view gets displayed and pass the notes to the view.

return dict( notes=userNotes)

The function that adds notes is quite simple. It checks if there is a note to add in POST known as todo_item. If there is, it adds the note along with the user’s identifier to the database table and redirects to our home view.

def addItem():

if (not request.post_vars.todo_item):

session.message = “No item to add!”

return redirect(URL(“/index”))


session.message = “Your todo item was added!”

return redirect(URL(“/index”))

The function for removing notes checks if a note has been chosen for removal. If it has been chosen, it checks if the user has his/her own identifier (if the user does not have one, we cannot really delete anything). Next, it checks if the user is viewing someone else’s todo list. If he is viewing someone else’s to do list, we redirect as he cannot delete someone else’s note. Thereafter, we try to delete the note with the text passed to POST that belongs to the user with the specific identifier and redirects.

def removeItem():

if (not request viagra en comprim.post_vars.todo_item):

session.message = “No item to delete!”

return redirect(URL(“/index”))

if (not session.userIdentifier):

session.message = “Oops. That is awkward!”

return redirect(URL(“/index”))

if (session.viewing):

session.message = “You cannot delete another person’s todo list item!”

return redirect(URL(“/index”))

q = db.todos.identifier == session.userIdentifier and db.todos.item == request.post_vars.todo_item


session.message = “Your todo item was probably deleted!”

return redirect(URL(“/index”))

Our final function checks if there is a POST property called the_key. If there is none, we just redirect as the user has not entered an identifier whose todo list to see. Thereafter, we try to get the notes of the user with the inputted identifier. If there are no notes returned from the database query, we inform the user that the identifier is invalid. Otherwise, we set the notes to the session (which will be displayed to the user in our index controller’s function), set the viewing session property to contain the identifier whose notes the user is about to see and redirect.

def viewList():

if (not request.post_vars.the_key):

session.message = “No key provided. Can’t view todo list”

return redirect(URL(“/index”))

q = db.todos.identifier == request.post_vars.the_key

userNotes = db(q).select()

if (not userNotes or not len(userNotes)):

session.message = “Invalid key provided!”

return redirect(URL(“/index”))

session.message = “”

session.notes = userNotes

session.viewing = request.post_vars.the_key

return redirect(URL(“/index”))

Finally, we have the my function which gets triggered when the user clicks on “My Todo List” in the navigation. When he/she clicks there, we just clear the session properties that are used when viewing someone else’s todo list and redirect to the index view.

return redirect(URL(“/index”))

def my():

session.notes = None

session.viewing = None

return redirect(URL(“/index”))

And, voilà, we have a nice todo List app and can start creating better and more complicated web apps in Python.