The article demonstrates building CRUD REST APIs using Django REST Framework (DRF) for a supermarket inventory system. It manages categories, subcategories, and products through RESTful endpoints that support creating, retrieving, updating, and deleting records.
Make sure Django is installed and configured before continuing. If not, refer to the following article for setup instructions:
Installation
Run the following command to install Django REST Framework:
pip install djangorestframework

After installing the REST framework, go to settings.py, and in INSTALLED_APPS add ‘rest_framework’ at the bottom.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
]
Creating App for Django REST Framework
Step 1: After installing DRF and adding it to settings.py, let's create an app using the command:
python manage.py startapp api
After executing the command, Django creates a new application named api within the project.

Step 2: Add this app to INSTALLED_APPS and urls.py also in, settings.py.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'api.apps.ApiConfig',
]
Step 3: Add the api URL patterns to the project's urls.py file. In gfg_shopping/urls.py, include the following code:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')),
]
Creating Model in Django
Create the Item model, which defines the data structure used by the API for CRUD operations.
from django.db import models
class Item(models.Model):
category = models.CharField(max_length=255)
subcategory = models.CharField(max_length=255)
name = models.CharField(max_length=255)
amount = models.PositiveIntegerField()
def __str__(self) -> str:
return self.name
Now after app gets ready, create the serializer for Item class.
ModelSerializer
The Item model must be converted into a format that can be sent and received through API requests. ModelSerializer handles this conversion automatically by generating serializer fields from the model, allowing CRUD operations to be implemented with minimal code.
Now create serlializers.py file in the api folder.
from django.db.models import fields
from rest_framework import serializers
from .models import Item
class ItemSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = ('category', 'subcategory', 'name', 'amount')
Create Views for Django
To render data into frontend, and handle requests from user, we need to create a view. In Django REST Framework, we call these viewsets, so create a view in apis/views.py,
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Item
from .serializers import ItemSerializer
@api_view(['GET'])
def ApiOverview(request):
api_urls = {
'all_items': '/',
'Search by Category': '/?category=category_name',
'Search by Subcategory': '/?subcategory=category_name',
'Add': '/create',
'Update': '/update/pk',
'Delete': '/item/pk/delete'
}
return Response(api_urls)
In the above code, the api_view decorator takes a list of HTTP methods that a views should response to. Other methods will response with the Method Not Allowed.
Update the api/urls.py file to register the API endpoints:
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home')
]
With the API configuration complete, start the development server using the following commands:
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
Now, head to http://127.0.0.1:8000/api/

CRUD Opetration with Django Rest Framework
Create View
To create new records through the API, define a view that handles POST requests. Add the following add_items function to views.py:
from rest_framework import serializers
from rest_framework import status
@api_view(['POST'])
def add_items(request):
item = ItemSerializer(data=request.data)
# validating for already existing data
if Item.objects.filter(**request.data).exists():
raise serializers.ValidationError('This data already exists')
if item.is_valid():
item.save()
return Response(item.data)
else:
return Response(status=status.HTTP_404_NOT_FOUND)
Register the create endpoint in urls.py so that incoming requests can be routed to the add_items view:
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
]
Visit http://127.0.0.1:8000/api/create/

Read View
To retrieve records from the database, create a view that handles GET requests. The view_items function returns all items by default and also supports filtering results based on category, subcategory, or item name.
In views.py
@api_view(['GET'])
def view_items(request):
# checking for the parameters from the URL
if request.query_params:
items = Item.objects.filter(**request.query_params.dict())
else:
items = Item.objects.all()
# if there is something in items else raise error
if items:
serializer = ItemSerializer(items, many=True)
return Response(serializer.data)
else:
return Response(status=status.HTTP_404_NOT_FOUND)
In urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
path('all/', views.view_items, name='view_items'),
]
Now visit http://127.0.0.1:8000/api/all/

Note: In addition to retrieving all records, the endpoint allows users to filter results by category or subcategory and search for specific items by name using query parameters.
If we visit http://127.0.0.1:8000/api/all/?category=food our search result will narrow down to:

Update View
To modify existing records, create an update endpoint that identifies an item using its primary key and updates the submitted data. Add the following update_items function to views.py:
In views.py
@api_view(['POST'])
def update_items(request, pk):
item = Item.objects.get(pk=pk)
data = ItemSerializer(instance=item, data=request.data)
if data.is_valid():
data.save()
return Response(data.data)
else:
return Response(status=status.HTTP_404_NOT_FOUND)
In urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
path('all/', views.view_items, name='view_items'),
path('update/<int:pk>/', views.update_items, name='update-items'),
]
Now head to http://127.0.0.1:8000/api/all/?name=potato

Delete View
To remove records from the database, create a view that handles DELETE requests. The delete_items function deletes a specific item identified by its primary key.
In views.py
@api_view(['DELETE'])
def delete_items(request, pk):
item = get_object_or_404(Item, pk=pk)
item.delete()
return Response(status=status.HTTP_202_ACCEPTED)
In urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
path('all/', views.view_items, name='view_items'),
path('update/<int:pk>/', views.update_items, name='update-items'),
path('item/<int:pk>/delete/', views.delete_items, name='delete-items'),
]
Now visit http://127.0.0.1:8000/api/item/pk/delete/. See the below GIF for better understanding.

Making Authenticated API Requests
The CRUD examples shown above uses open endpoints for simplicity. In real-world applications, APIs are often secured using authentication mechanisms such as Token Authentication or JWT Authentication.
Once authentication is enabled, clients must include a valid token in the request headers.
Example: Fetching Student Records with Token Authentication
curl -X GET http://127.0.0.1:8000/students/ \
-H "Authorization: Token your_token_here"
Output
[
{
"id": 1,
"name": "Mike",
"roll": 101,
"city": "New York"
}
]
Explanation:
- The Authorization header contains the authentication token.
- The API verifies the token before processing the request.
- If the token is valid, the requested data is returned.
- If the token is missing or invalid, the API responds with an authentication error.
Note: This tutorial focuses on implementing CRUD operations with Django REST Framework. To learn how to secure your API endpoints using token-based authentication, refer to the article Implement Token Authentication using Django REST Framework.