FastAPI - Beginner to Pro / Project 5 - Full Stack Application

Full Stack - Edit Todo

πŸ“ Introduction: Editing a To-Do

In this lesson, we will create a page to edit existing tasks.

Users will be able to:

  • Update the title and description of a task ✏️.

  • Change the priority 🎯.

  • Mark a task as complete βœ….

This allows users to manage their tasks dynamically.

In the templates folder, create a new file edit-todo.html:


πŸ—οΈ Step 1: Create the Edit To-Do Template

  1. In the templates folder, create a new file edit-todo.html:

edit-todo.html
  1. Delete all auto-generated content.

  2. Include the main layout so the page inherits styles and navigation:

{% include 'layout.html' %}
  1. Add a container and card structure for consistent styling:

<div class="container">
  <div class="card">
    <div class="card-header">
      Edit Your To-Do
    </div>
    <div class="card-body">
      <form id="edit-todo-form">
        <!-- Form fields will go here -->
      </form>
    </div>
  </div>
</div>

✏️ Step 2: Add Form Fields

Inside the edit-todo-form, we need fields for title, description, priority, and completion status:

  1. Title:

<div class="form-group">
  <label>Title</label>
  <input type="text" class="form-control" name="title"
         value="{{ todo.title }}" required>
</div>
  1. Description:

<div class="form-group">
  <label>Description</label>
  <textarea class="form-control" name="description" rows="3" required>
    {{ todo.description }}
  </textarea>
</div>
  1. Priority (auto-selected based on current task):

<div class="form-group">
  <label>Priority</label>
  <select name="priority" class="form-control">
    {% for i in range(1,6) %}
      <option value="{{ i }}" {% if todo.priority == i %}selected{% endif %}>{{ i }}</option>
    {% endfor %}
  </select>
</div>
  1. Completion Checkbox:

<div class="form-group form-check">
  <input type="checkbox" class="form-check-input" name="complete"
         {% if todo.complete %}checked{% endif %}>
  <label class="form-check-label">Complete</label>
</div>

πŸ’Ύ Step 3: Add Buttons

Add buttons for submitting changes or going back to the to-do list:

<button type="submit" class="btn btn-primary">Edit To-Do</button>
<a href="/todos/todo-page" class="btn btn-success">Back</a>

πŸš€ Step 4: Create the Edit To-Do Endpoint in todos.py

  1. Add a new route for the edit page:

@router.get("/edit-todo-page/{todo_id}")
async def edit_todo_page(request: Request, todo_id: int, db: Session = Depends(get_db)):
    try:
        user = await get_current_user(request.cookies.get("access_token"))
        if not user:
            return redirect_to_login()

        todo = db.query(ToDos).filter(ToDos.id == todo_id).first()
        return templates.TemplateResponse(
            "edit-todo.html", {"request": request, "todo": todo, "user": user}
        )
    except:
        return redirect_to_login()
  • todo_id allows fetching the correct task.

  • The user is verified via the JWT token from cookies.

  • If invalid, the user is redirected to login.


πŸ”„ Step 5: Test the Edit To-Do Page

  1. Run your FastAPI app:

uvicorn app.main:app --reload
  1. Sign in as a test user (e.g., codingwithRuby, password test1234!).

  2. Go to the home page and click Edit on any existing to-do.

  3. Change the title, description, priority, or completion status and click Edit To-Do.

  4. Verify that changes are reflected on the home page.


βœ… Step 6: Summary

  • We created a dynamic Edit To-Do page with title, description, priority, and completion fields.

  • The page fetches the current task using Jinja template variables.

  • Changes are submitted via the form (handled by JavaScript in base.js).

  • Users are redirected to login if their token is invalid, keeping the application secure.

  • Next step: Delete To-Dos to fully manage tasks.