Lesson 3
Implementing Alphanumeric Data Sorting
Implementing Alphanumeric Data Sorting

Welcome back! In the previous lessons, we set up SQLAlchemy, mapped our Todo model to a database table, and performed CRUD operations. This lesson focuses on enhancing our ToDo application by adding the ability to sort todos.

Sorting is an essential feature in any web application, as it improves user experience by making data easier to navigate and find. Today, we will learn how to implement this functionality step-by-step.

What is Sorting?

Before diving deeper, let's briefly remind ourselves of what sorting is.

Sorting arranges data in a specific order. Common types of sorting include:

  • Alphabetical: Orders data from A-Z (ascending) or Z-A (descending).
  • Numerical: Orders numbers in an ascending (0-9) or descending (9-0) sequence.
  • Alphanumeric: Sorts data containing both letters and numbers, typically placing numbers before letters (e.g., '1 Task', '2 Task', 'Task 1', 'Task 2', 'Task 10').

In this lesson, we will implement alphanumeric sorting by the todo titles to help users find items more quickly.

Implementing Sorting in the Service Layer

Let’s start by updating the get_all method in app/services/todo_service.py to support sorting.

Here’s the updated method:

Python
1from models.todo import Todo, db 2 3class TodoService: 4 @staticmethod 5 def get_all(sort_by=None): 6 # Initialize a query on the Todo model 7 query = Todo.query 8 # Apply sorting if sort_by is 'title' 9 if sort_by == 'title': 10 query = query.order_by(Todo.title) 11 # Execute the query and return all matching todos 12 return query.all()

Let's break this down:

  1. Initial Query:
    • We start by initializing a query on the Todo model: query = Todo.query. This sets up a base query to build on.
  2. Sorting:
    • If sort_by is set to 'title', we sort the results: query = query.order_by(Todo.title). This arranges the todos alphanumerically by their titles. If sort_by is anything other than 'title', all items will be fetched without sorting.
  3. Fetching Results:
    • Finally, return query.all() executes the query and returns all matching todos.
Updating the Controller to Handle Sorting

Now, we’ll modify app/controllers/todo_controller.py to capture the sort parameter from the URL and pass it to our updated service method.

Here’s the updated controller:

Python
1from flask import Blueprint, render_template, request, redirect, url_for 2from services.todo_service import TodoService 3 4todo_service = TodoService() 5todo_controller = Blueprint('todo', __name__) 6 7@todo_controller.route('/', methods=['GET']) 8def list_todos(): 9 # Capture sort parameter from the URL 10 sort_by = request.args.get('sort_by') 11 # Fetch sorted todos 12 todos = todo_service.get_all(sort_by=sort_by) 13 # Render the todo list template with the todos 14 return render_template('todo_list.html', todos=todos)

Let's break this down:

  1. Capturing Parameter:

    • We capture the sort_by parameter from the URL query string using sort_by = request.args.get('sort_by'). This allows us to dynamically read this value whenever a GET request is made to the root route (/).
  2. Fetching Sorted Data:

    • We call todo_service.get_all(sort_by=sort_by) with the captured parameter. This fetches the todos based on the sort criteria specified by the user. If the sort_by parameter is None, the method will return all todos.
  3. Rendering the Template:

    • We render the todo_list.html template with the fetched todos using return render_template('todo_list.html', todos=todos). This passes the sorted list of todos to the template for display.
Modifying the Template for User Input

The final step is to modify app/templates/todo_list.html to add sort options in the form, enabling users to input their preferences.

Here’s the updated template:

HTML, XML
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Todo List</title> 7</head> 8<body> 9 <h1>Todo List</h1> 10 11 <!-- Form for sorting todos --> 12 <form action="{{ url_for('todo.list_todos') }}" method="GET"> 13 <div class="form-group"> 14 <label for="sort_by">Sort by:</label> 15 <select id="sort_by" name="sort_by"> 16 <option value="" selected>None</option> 17 <option value="title">Title</option> 18 </select> 19 </div> 20 <button type="submit">Apply</button> 21 </form> 22 23 <!-- List all todos... --> 24 25 <!-- Form for adding a new todo... --> 26 27</body> 28</html>

Key Additions:

  1. Form Setup: A form that submits GET requests to the list_todos route.
  2. Sort By Dropdown: A dropdown menu to select sorting by title, with "None" as the default option.
  3. Submit Button: A button to apply the selected sort option.

If no sorting option is selected, the submit button will send None to the sort_by parameter, resulting in all todos being returned. These enhancements enable users to specify their sorting preferences, while still allowing for all items to be displayed if no specific options are chosen. When the form is submitted, the selected options are sent as query parameters to the list_todos route, which then displays the sorted list of todos.

Sorting in Practice

Now that we have implemented sorting, it’s essential to test the functionality.

  1. Sorting:

    • Use the sort dropdown to select "Title" and submit the form.
    • The URL for sorting by title would be: /todos?sort_by=title
    • The items should be sorted alphanumerically by title.
  2. Returning All Todos:

    • Submit the form without selecting a sort option.
    • The URL for returning all todos would be: /
    • All todos should be displayed without any sorting applied.
Summary and Preparation for Practice

In this lesson, we enhanced our ToDo application by implementing sorting functionality. We:

  1. Updated the service layer to support dynamic sorting.
  2. Modified the controller to capture user input for sorting.
  3. Enhanced the template to allow users to input their sorting preferences.
  4. Provided strategies to test the new functionality.

These improvements make our application more robust and user-friendly. Now it’s time for you to practice these concepts. Head over to the practice exercises to solidify your understanding and gain hands-on experience with implementing sorting.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.