Django Rest Framework (DRF) is a comprehensive toolkit for building Web APIs with Django. It offers serialization, authentication, viewsets, and interactive documentation, making it an excellent choice for developing reliable and maintainable RESTful services.
In this tutorial, you'll build a task management API using Django Rest Framework and SQLite as the database backend.
Prerequisites
Before getting started, ensure you have:
- Python installed on your system (preferably Python 3.13 or higher)
- A basic understanding of Python, Django, and web development concepts
Step 1 — Setting up the Django Rest Framework project
In this section, you'll create the directory structure and install the necessary dependencies for the Django Rest Framework project.
First, create a new directory for your project and navigate into it:
Next, create a virtual environment and activate it:
Install Django and the Django Rest Framework:
Here's a breakdown of these packages:
Django– The web framework that forms the foundation.Django Rest Framework– The toolkit for building REST APIs with Django.
After that, create a new Django project:
Next, create a new Django app for handling tasks:
Now, update the settings.py file to include Django Rest Framework and your new app. Open taskmanager/settings.py and find the INSTALLED_APPS list:
Next, configure Django Rest Framework by adding some settings at the bottom of the settings.py file:
This configuration sets up some basic defaults:
DEFAULT_PERMISSION_CLASSESdetermines who can access your API. We're starting withAllowAnyfor simplicity.DEFAULT_PAGINATION_CLASSandPAGE_SIZEconfigure automatic pagination of results, limiting responses to 10 items per page.
The default database configuration in settings.py uses SQLite, perfect for this tutorial. The configuration looks like this:
With that, run initial migrations to set up your database:
You should see output similar to:
Now run the development server:
You should see output similar to:
Your Django application is now running with SQLite as the database. If you navigate to http://127.0.0.1:8000/ in your browser, you should see the default Django welcome page:
With Django now running, you'll define the data model for tasks in the next step.
Step 2 — Creating the Task model
With the Django project set up, you will define a model for your tasks. Django models specify your application's data's database schema and business logic.
Start by opening the tasks/models.py file generated when you created your app. Modify this file to define the Task model:
This model includes:
- A UUIDField for unique task IDs.
- A CharField for titles, indexed for faster searches.
- A TextField for optional descriptions.
- An IntegerField for priority, defaulting to 1.
- A BooleanField to track completion status.
- DateTimeFields for creation and update timestamps.
- Default ordering by newest tasks first.
Now that you've defined your model, you need to create and apply a database migration. Migrations are Django's way of tracking and applying changes to your database schema.
First, create a migration file:
You should see output similar to:
This creates a new file in the tasks/migrations directory that describes the changes to be made to the database.
Next, apply the migration to create the database table:
You should see output that includes:
Verify your model is working correctly by creating a task through Django's shell:
In the shell, paste these commands:
You should see a message confirming the task was created, with a UUID and the title "Test Task":
Now, register your model with Django's admin interface so you can easily view and edit tasks:
This sets up an admin interface for the Task model with:
- A customized list view showing key fields
- Filters for completion status and priority
- Search capability across title and description
- Protection for system-managed fields like IDs and timestamps
To access the admin interface, you'll need to create a superuser:
Follow the prompts to create an admin account, then start the development server again:
You can visit http://127.0.0.1:8000/admin/ and log in with your superuser credentials to view and manage tasks:
Now that you have defined and worked on your data model, the next step is creating serializers to convert Django models and JSON representations suitable for your API.
Step 3 — Creating serializers for the Task model
Django Rest Framework uses serializers to convert complex data types, like Django model instances, to Python data types easily rendered into JSON, XML, or other content types. Serializers also handle deserialization, allowing parsed data to be converted into complex types after validation.
To create serializers for your Task model, first create a new file in the tasks app:
Now, open the newly created serializers.py file and add the following code:
This serializer automatically generates fields based on the Task model and ensures that specific fields, such as id, created_at, and updated_at, remain read-only. It also includes custom validation to restrict the priority value between 1 and 5.
While you could use this single serializer for all operations, it's often better to create specialized serializers for different actions.
Add two more serializers to handle creating and updating tasks specifically:
These serializers serve specific purposes:
TaskCreateSerializeris used to create new tasks, including only relevant fields and enforce priority validation.TaskUpdateSerializeris designed for updates, making all fields optional so clients can modify only what they need.
You can test these serializers in the Django shell:
In the shell, try converting a task to and from JSON by paste the following:
The output should include the serialized task data in Python dict format, followed by the JSON representation:
The output demonstrates serializing a Task instance using Django Rest Framework. First, it retrieves a task from the database and serializes it into a Python dictionary.
Then, the data is converted into a JSON string using JSONRenderer. The final output includes the dictionary and JSON representation, which are ready for API responses.
Your serializers are now ready to convert Django models and API responses. In the next step, you'll implement views and URLs to expose your API endpoints.
Step 4 — Implementing views and URLs for task operations
Django Rest Framework provides several types of views to handle API requests. In this step, you'll implement ViewSets, which combine the logic for multiple related operations into a single class, simplifying your API implementation.
Start by creating the views for your task operations. Open the tasks/views.py file and replace its contents with:
This TaskViewSet serves as the main entry point for handling task-related API operations. It retrieves all tasks by default but allows filtering based on completion status when a query parameter is provided.
The get_serializer_class() method dynamically selects the appropriate serializer depending on the action. When creating a new task, it uses TaskCreateSerializer, while updates rely on TaskUpdateSerializer.
For all other actions, such as listing or retrieving tasks, it defaults to TaskSerializer.
Next, you must set up the URL patterns to expose your API endpoints. Create the tasks/urls.py file with the following:
The DefaultRouter automatically creates the following URL patterns:
GET /tasks/- List all tasks (with optional filtering)POST /tasks/- Create a new taskGET /tasks/{id}/- Retrieve a specific taskPUT /tasks/{id}/- Update a task completelyPATCH /tasks/{id}/- Update a task partiallyDELETE /tasks/{id}/- Delete a task
Finally, update the main URLs file to ensure your app's URLs are included in the project. Open taskmanager/urls.py and make sure it includes the tasks app URLs:
With your views and URLs configured, your API is now ready for testing. Start the development server:
Now you can test your API using curl or any API client.
You can create a new task by sending a POST request to the /api/tasks/ endpoint:
You should receive a response with the newly created task:
To retrieve a list of all tasks, send a GET request to the /api/tasks/ endpoint:
This should return a paginated response with all your tasks:
Retrieve a specific task (replace with your actual task ID):
Remember to replace <your_task_id> with an actual UUID from your database. You should receive a response with the requested task:
Update an existing task by sending a PUT request to the /api/tasks/<task_id>/ endpoint:
Remove a task by sending a DELETE request to the /api/tasks/<task_id>/ endpoint:
The 204 status code indicates the task was successfully deleted, and no content is returned in the response body.
Django Rest Framework also provides a browsable API you can access through your web browser. Visit http://127.0.0.1:8000/api/tasks/ to see and interact with your API directly in the browser:
You've implemented a fully functional API with endpoints for creating, reading, updating, and deleting tasks.
Final thoughts
This tutorial has walked you through creating a task management API with Django Rest Framework and SQLite. Django Rest Framework's elegant, Pythonic design makes it ideal for API development.
For more insights into advanced topics like throttling, permissions, and authentication, check the official docs for Django, and Django Rest Framework.
Thanks for reading, and happy coding!