Lesson 3
Updating a To-Do
Introduction

Welcome to the lesson on updating To-Do items! In this lesson, we will focus on updating existing To-Do items using the Django REST framework. By the end of this lesson, you will be able to create an endpoint that allows users to modify their To-Dos, and you will understand how to test this functionality with HTTP requests.

Imagine a user made a typo when creating a new ToDo in our app and wants to fix it. Updating a resource is a critical part of RESTful architecture, where the PUT method allows you to modify an existing record. In this context, we will build upon the previous lessons where we learned to create and retrieve To-Dos. Let’s dive in!

Recap of Prior Setup

Before we proceed, let's quickly recap the fundamental setup we've done so far. This includes defining our model and serializer for To-Do items. Here’s a brief reminder of what our models.py and serializers.py look like:

myproject/myapp/models.py

Python
1from django.db import models 2 3class Todo(models.Model): 4 task = models.CharField(max_length=255) 5 completed = models.BooleanField(default=False) 6 7 def __str__(self): 8 return self.task

myproject/myapp/serializers.py

Python
1from rest_framework import serializers 2from .models import Todo 3 4class TodoSerializer(serializers.ModelSerializer): 5 class Meta: 6 model = Todo 7 fields = ['id', 'task', 'completed']

With these essential components set up, we're ready to create the update view.

Creating the Update API View

To enable updating To-Do items, we will use the UpdateAPIView class from the Django REST framework. Here’s how you can create the Update view:

myproject/myapp/views.py

Python
1from rest_framework import generics 2from .models import Todo 3from .serializers import TodoSerializer 4 5class TodoUpdate(generics.UpdateAPIView): 6 queryset = Todo.objects.all() 7 serializer_class = TodoSerializer

Explanation:

  • We import generics from rest_framework.
  • We define a class TodoUpdate that inherits from generics.UpdateAPIView.
  • We set queryset to Todo.objects.all(), which retrieves all To-Do items from the database.
  • We assign TodoSerializer to serializer_class to determine the structure of our data.

This view will handle PUT and PATCH requests to update an existing To-Do item. As you can see, creating it is straightforward and very similar to other generics we tried. However, again, it is vital to understand the details of how it is used.

How the PUT Request Works

The PUT method in REST architecture is used to update an existing resource in its entirety. When you use the PUT method, you send the complete representation of the resource you want to update. If parts of the resource are not included in the request, they will be overwritten with default or empty values. This is why it’s important to include all required fields in the PUT request.

For example, consider the following PUT request to update a To-Do item:

Python
1updated_todo = {'task': 'Updated task', 'completed': True} 2put_response = requests.put(update_url, json=updated_todo)

In this case, both the task and completed fields are included. If any field were omitted, it would be reset to its default value.

The PATCH Request

The PATCH method is similar to PUT but is used for partial updates. When you use the PATCH method, you only need to send the fields you want to update. This means you can update one or more fields of an existing resource without impacting other fields.

For example, consider the following PATCH request to update only the task field of a To-Do item:

Python
1partial_update_todo = {'task': 'Partially updated task'} 2patch_response = requests.patch(update_url, json=partial_update_todo)

In this case, only the task field will be updated, and the completed field will remain unchanged.

Setting Up the URLs

We need a way to retrieve the details of a specific To-Do item to confirm that it has been updated correctly. For this purpose, we'll use TodoDetail view from the previous unit. To make our views accessible through specific endpoints, we'll configure our URLs in urls.py.

myproject/myapp/urls.py

Python
1from django.urls import path 2from .views import TodoUpdate, TodoDetail, TodoListCreate 3 4urlpatterns = [ 5 path('todos/', TodoListCreate.as_view(), name='todo_list_create'), 6 path('todos/update/<int:pk>/', TodoUpdate.as_view(), name='todo_update'), 7 path('todos/<int:pk>/', TodoDetail.as_view(), name='todo_detail'), 8]

Explanation:

  • We import the necessary views: TodoUpdate, TodoDetail, and TodoListCreate.
  • We add paths for todo_update and todo_detail with placeholders <int:pk> to identify specific To-Do items by their primary key.
  • To distinguish endpoints for update and retrieve, we add /update/ to the URL mapped to the TodoUpdate view.

This ensures our API can handle requests to update and retrieve specific To-Do items.

Practical Scenarios for Using the Update Endpoint

Here are some practical scenarios where an update endpoint is essential:

  • Correcting Mistakes: Users may make typos or other errors when creating a To-Do item and need to correct those errors.
  • Changing Status: Users may need to mark tasks as completed or change their status back to incomplete.
  • Adding Details: Initially, a user might create a To-Do item with minimal information and later decide to add more details.

By providing an update endpoint, our To-Do application becomes more flexible and user-friendly, allowing users to manage their tasks more effectively.

Testing the Update and Retrieve Views

Let's test the functionality of the update and retrieve views using Python's requests library.

send_request.py

Python
1import requests 2 3URL = 'http://127.0.0.1:8000/api/todos/' 4 5# Create a new To-Do item to ensure the database is not empty 6new_todo = {'task': 'Initial task'} 7post_response = requests.post(URL, json=new_todo) 8print(post_response.json()) # Expect to see the newly created TODO item 9 10# Update the newly created To-Do item 11todo_id = post_response.json()['id'] 12update_url = f'http://127.0.0.1:8000/api/todos/update/{todo_id}/' 13updated_todo = {'task': 'Updated task', 'completed': True} 14put_response = requests.put(update_url, json=updated_todo) 15print(put_response.json()) # Expect to see the updated TODO item 16 17# Partially update the To-Do item 18partial_update_todo = {'task': 'Partially updated task'} 19patch_response = requests.patch(update_url, json=partial_update_todo) 20print(patch_response.json()) # Expect to see the partially updated TODO item 21 22# Retrieve the updated To-Do item 23retrieve_url = f'http://127.0.0.1:8000/api/todos/{todo_id}/' 24get_response = requests.get(retrieve_url) 25print(get_response.json()) # Expect to see the details of the updated TODO item

Explanation:

  • We define the base URL for our API.
  • We create a new To-Do item to ensure the database isn't empty and print the response.
  • We update the newly created To-Do item using its ID and print the updated response.
  • We partially update the To-Do item using its ID and print the partial update response.
  • Finally, we retrieve the updated To-Do item and print its details to verify the update.
Review, Summary, and Next Steps

In this lesson, we covered the essentials of updating To-Do items in a Django REST API. You learned how to create UpdateAPIView, configure URL for it, and test the endpoints using HTTP requests.

Key Points Recap:

  • Use UpdateAPIView to update existing resources.
  • Use RetrieveAPIView to fetch details of specific resources.
  • Configure URLs to ensure accessibility of these views.
  • Practical scenarios include correcting mistakes, changing status, and adding details.
  • The PUT method is for full updates, while the PATCH method is for partial updates.

With this knowledge, you can create, retrieve, and update To-Do items in your Django REST API. Make sure to practice these concepts with the following exercises to solidify your understanding.

Congratulations on getting through this lesson. Continue practicing, and you'll become proficient in handling CRUD operations with the Django REST framework. Happy coding!

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