
Django REST Framework (DRF) is one of the most powerful and flexible tools for building RESTful APIs in Python. This article will guide you step by step through the process of creating your first API endpoint, covering the use of serializers, views, and URL routing.
In my previous article, we discussed how to structure your first Django project. If you haven’t seen it yet, click here, as we’ll pick up right where we left off.
Objectives
- Understand the role of Django REST Framework and why it is useful.
- Create a simple API endpoint for resource management.
- Execute GET and POST requests to read and write data.
So, if you followed my previous article on Django, you already have a configured Django project. Now, let’s see how to expose data through an API.
Django REST Framework (DRF) is an open-source framework that extends Django to build RESTful web APIs. It provides a complete set of tools for:
- Advanced Serialization: Converts Django model instances into formats (JSON, XML) usable by client applications and vice versa, ensuring data validation and custom field management.
- View classes and ViewSets: Generic classes (e.g., ListCreateAPIView, RetrieveUpdateDestroyAPIView) and ViewSets to handle CRUD operations while minimizing boilerplate code.
- Smart Routing: Automatic routers that dynamically associate ViewSets with URL routes, simplifying the definition of endpoints.
- Authentication and Authorization: Native support for authentication methods (SessionAuth, TokenAuth, JWT) and permission classes to control access to resources.
- Throttling, Filtering, and Pagination: Built-in mechanisms to limit requests, filter results, and paginate responses.
- Browsable API: An interactive HTML interface to explore and test endpoints during development.
It has a fairly intuitive workflow divided into serializers, views, and routers:
- Serializers: These handle the conversion between Python objects (typically Django model instances) and serialized representations (JSON, XML).
- Views: DRF views process HTTP requests and return serialized responses. DRF offers generic classes (e.g., GenericAPIView, ListAPIView, CreateAPIView, etc.) for common operations. ViewSets aggregate multiple actions (list, create, retrieve, update, destroy) into a single class, working in synergy with Routers to reduce code further.
- Routers: Routers automatically connect ViewSet actions to URL patterns. For example, by using DefaultRouter, you get endpoints like
/notes/
for list/create and/notes/{pk}/
for retrieve/update/delete, without needing to manually write each URL.
Environment Setup
Installation
Make sure Django is installed, and then add Django REST Framework:
pip install djangorestframework
Add it to the installed apps in settings.py
:
INSTALLED_APPS = [
...
'rest_framework',
]
Code language: JavaScript (javascript)
Creating the model
Let’s define a simple model for a note:
from django.db import models
class Note(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
After defining the model, apply the migrations:
python manage.py makemigrations
python manage.py migrate
Code language: CSS (css)

Creating the Serializer
Let’s create a file inside our app directory and name it serializers.py.

The serializers convert the database data into JSON format.
from rest_framework import serializers
from .models import Note
class NoteSerializer(serializers.ModelSerializer):
class Meta:
model = Note
fields = '__all__'
Creating the View
Open the views.py
file and delete all the existing code inside it.
We will use a ListCreateAPIView
, which allows retrieving the list of items (GET) and creating new ones (POST):
from rest_framework import generics
from .models import Note
from .serializers import NoteSerializer
class NoteListCreateView(generics.ListCreateAPIView):
queryset = Note.objects.all()
serializer_class = NoteSerializer
Configuring the URLs
Let’s add a URL for our API, so open the urls.py
file within our app:
from django.urls import path
from .views import NoteListCreateView
urlpatterns = [
path('notes/', NoteListCreateView.as_view(), name='note-list-create'),
]
Code language: JavaScript (javascript)
In the main project’s urls.py
file:
from django.urls import path, include
urlpatterns = [
path('api/', include('nome_app.urls')),
]
Code language: JavaScript (javascript)
The Browsable API of Django REST Framework
Django REST Framework includes a built-in Browsable API that allows you to explore and interact with your endpoints directly from the browser, without needing to use other tools like Postman or curl. It’s a true dynamic HTML user interface that:
- Displays resources: lists available fields, their types, and current values in a clear and readable format.
- Supports CRUD operations: automatically provides forms to send GET, POST, PUT, and DELETE requests, filling in fields based on the serializer.
- Manages authentication: allows users to log in via session or token directly from the interface, hiding or showing links based on permissions.
- Shows errors: highlights validation errors with detailed messages next to fields, making debugging easier.
No additional configuration is required to enable it: simply include ‘rest_framework’ in INSTALLED_APPS and access the URL in the browser (e.g., http://127.0.0.1:8000/api/notes/). The Browsable API is especially useful during development because it allows you to quickly test endpoints, check the data format, and visually understand the structure of JSON responses.
API Testing
We can test our endpoint using tools like curl or Postman, or by using the browsable API included in Django REST Framework.
Now, let’s open the terminal and type:
python manage.py runserver
Code language: CSS (css)

Example of a GET request:
curl http://127.0.0.1:8000/api/notes/
Code language: JavaScript (javascript)
Example of a POST request:
curl -X POST -H "Content-Type: application/json" -d '{"title": "Test", "content": "Contenuto della nota"}' http://127.0.0.1:8000/api/notes/
Code language: JavaScript (javascript)
Alternatively, using the browsable API:


If everything is working correctly, you should see the data returned in JSON format.

Best Practices
Error Handling
DRF automatically handles common errors, but we can customize error messages if necessary.
Security
To secure the API, you can implement authentication and authorization using DRF’s built-in mechanisms, such as Token Authentication or JWT.
Modularity
For more complex projects, DRF provides ViewSets and Routers, which simplify the management of APIs.
Next Steps
We have seen how to create a simple REST APIs with Django REST Framework, including:
- Defining a model,
- Creating a serializer,
- Implementing a view,
- Configuring URLs,
- Testing the API with GET and POST.
Now, you’re ready to develop more complex APIs and enhance your skills further!