Using Databases from Applications

Project Checkpoint


In the regular chapters of this part, the examples and exercises focused on the tags table. You added functionality for listing tags, showing the newest tag, creating tags, deleting tags, and updating one chosen tag, and all of the user-input queries used the safe parameterized t-string pattern.

In this part’s project checkpoint, you apply those same patterns to the existing decks feature. The project already has a small read flow for decks; now, you turn it into a full CRUD flow.

Goal

Implement one-table CRUD functionality for decks through the web application.

By the end of this step, the project should have the following visible functionality:

  • a user can read deck data on /decks,
  • a user can read the newest deck on /decks/newest,
  • a user can create one new deck from a form,
  • a user can edit one chosen deck,
  • and a user can delete one chosen deck.

Suggested Sequence

Approach this milestone by extending the functionality one step at a time.

  1. In app/main.py, keep the existing GET /decks route working.
  2. Keep the existing GET /decks/newest route working.
  3. Add a simple create form to app/templates/decks.html.
  4. Add the matching POST route that inserts one new deck and redirects back to /decks. Use a parameterized t-string, exactly as in the tag examples.
  5. Add an Edit link on each deck row on /decks.
  6. Add a GET /decks/{deck_id}/edit route that loads one chosen deck for editing.
  7. Add one template for the edit form.
  8. Add the matching POST route that updates the chosen deck and redirects back to /decks.
  9. Add a Delete deck button for one chosen deck on /decks.
  10. Add the matching POST route that deletes that one deck and redirects back to /decks.
  11. If you want, add a shared base.html template and stable navigation links after the visible CRUD flow is already working.

That order matters. If the list page breaks while forms and edit routes are being added at the same time, it becomes much harder to tell whether the problem is in the route, the template, or the SQL.

Use the existing render() helper from the walking skeleton consistently, the same way the chapter-level tag routes do.

One useful way to think about this milestone is to trace one full create flow:

  1. the browser shows a form on /decks,
  2. the user submits the form,
  3. FastAPI receives a POST request,
  4. the route reads the submitted values,
  5. a parameterized INSERT query stores the new row,
  6. the route redirects back to /decks,
  7. the list route runs its SELECT,
  8. and the template renders the updated list.

If you can explain that sequence for your own code, the create part of the milestone is in good shape. The same kind of trace can then be applied to the edit and delete flows.

Common pitfalls
  • Building SQL strings directly from input instead of using the t-string form.
  • Dropping or forgetting the t prefix and leaving an f-string that only looks parameterized.
  • Forgetting to redirect after a successful write.
  • Updating or deleting the wrong row because the identifier was not passed carefully.
  • Putting action pages such as edit or delete into the top-level navigation.
  • Trying to add multi-table features before the one-table flow is solid.

Project Checkpoint

The embedded checkpoint below contains the exact tested labels, return instructions, and grading requirements.

If you also want to keep the project organized while you build it, you can reuse the Chapter 9 ideas after the required CRUD flow is complete.

Loading Exercise...