How to Add or Update Multiple Data Entries in Django REST API with a Script

Managing bulk data in web applications, especially when adding or updating multiple entries, can be both essential and challenging. In Django REST Framework (DRF), the ability to handle bulk data operations can greatly improve performance and efficiency. In this article, we’ll explore how to create a script to add or update multiple data entries in a Django REST API.
Why Bulk Operations?
Bulk operations are particularly useful for large data sets. Performing these operations individually can lead to numerous database hits, slowing down your application. By implementing bulk create and update methods, you reduce the number of database interactions, thereby boosting performance and efficiency.
Step 1: Set Up the Django REST API Project
Before we start, make sure you have a Django project and app created with Django REST Framework installed. You can create these by running the following commands:
django-admin startproject bulk_api
cd bulk_api
python manage.py startapp api
Now, install Django REST Framework if you haven’t already:
pip install djangorestframework
In your settings.py
file, add 'rest_framework'
and your app (e.g., 'api'
) to INSTALLED_APPS
.
INSTALLED_APPS = [
...
'rest_framework',
'api',
]
Create your database models in api/models.py
. For demonstration, we'll use a simple Product
model with fields for name
, description
, and price
.
# api/models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
def __str__(self):
return self.name
Run migrations to apply the model to your database:
python manage.py makemigrations
python manage.py migrate
Step 2: Set Up Serializers and Views for Bulk Operations
In api/serializers.py
, create a serializer for the Product
model:
# api/serializers.py
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
Now, create a view to handle bulk create and update operations. In api/views.py
, define a view that uses the serializer to handle lists of products.
# api/views.py
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import Product
from .serializers import ProductSerializer
from django.db import transaction
class ProductBulkView(APIView):
def post(self, request):
# Handling bulk create
serializer = ProductSerializer(data=request.data, many=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def put(self, request):
# Handling bulk update
data = request.data
with transaction.atomic():
for item in data:
product, created = Product.objects.update_or_create(
id=item.get('id'),
defaults={
'name': item.get('name'),
'description': item.get('description'),
'price': item.get('price'),
}
)
return Response({'status': 'Updated products successfully'}, status=status.HTTP_200_OK)
In this view:
- The
post
method is used to handle bulk creation, using theProductSerializer
withmany=True
. - The
put
method is used to handle bulk updates, whereupdate_or_create
checks if each product exists based on itsid
. If it exists, it updates the product, otherwise, it creates a new one.
Step 3: Add URL Patterns
To enable the bulk operations view, add the URL pattern in api/urls.py
.
# api/urls.py
from django.urls import path
from .views import ProductBulkView
urlpatterns = [
path('products/bulk/', ProductBulkView.as_view(), name='product-bulk'),
]
Include these URLs in your project’s main urls.py
file.
# bulk_api/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')),
]
Step 4: Write a Script to Add or Update Data in Bulk
Create a script to send requests with multiple entries to the API endpoint. Use Python’s requests
library to interact with the API.
Install the requests library if necessary:
pip install requests
Here’s an example script to add and update multiple entries:
# bulk_operations_script.py
import requests
API_URL = "http://127.0.0.1:8000/api/products/bulk/"
# Data to add or update
data = [
{"id": 1, "name": "Product A", "description": "Updated description", "price": 9.99},
{"id": 2, "name": "Product B", "description": "New product B", "price": 14.99},
{"id": 3, "name": "Product C", "description": "New product C", "price": 19.99},
]
# Function to add or update multiple products
def bulk_update_products(data):
try:
# Sending a PUT request to update data
response = requests.put(API_URL, json=data)
if response.status_code == 200:
print("Products updated successfully.")
else:
print("Failed to update products:", response.status_code, response.json())
except Exception as e:
print("An error occurred:", e)
bulk_update_products(data)
Run the script using:
python bulk_operations_script.py
This script sends a PUT request to your API to add or update the list of products. Products with existing IDs will be updated, while those without IDs will be added as new entries.
Step 5: Testing the Endpoint
You can test the bulk addition and update by sending a POST or PUT request to the /api/products/bulk/
endpoint, either using the script above, or with a tool like Postman to send sample JSON data.
Here’s a sample JSON payload for adding new products:
[
{"name": "Product D", "description": "Description of product D", "price": 24.99},
{"name": "Product E", "description": "Description of product E", "price": 29.99}
]
And for updating existing products:
[
{"id": 1, "name": "Updated Product A", "description": "Updated description", "price": 9.99},
{"id": 2, "name": "Updated Product B", "description": "Updated description", "price": 14.99}
]
Wrapping Up
Using bulk operations in Django REST API can significantly enhance performance when dealing with large datasets. By implementing a custom endpoint with update_or_create
, you can efficiently manage multiple entries in your database with a single API call. This method reduces database overhead and can make your application much more efficient.