How to make an API-based carousel using Django?
Last Updated :
25 Jan, 2024
In web development, carousels are widely used to showcase a dynamic set of images or content interactively. They prove popular for displaying products, portfolios, or any content that benefits from an engaging visual presentation. This tutorial will guide you through the process of creating an API-based carousel using Django—a robust web framework for Python—and Bootstrap, a front-end framework known for crafting responsive and visually appealing web pages.
What is a Carousel?
A carousel, also referred to as an image slider or image carousel, is a web component that enables the sequential display of multiple images or content items. Users can manually navigate through these items or opt for automatic cycling. Navigation controls such as arrows or dots are typically provided for users to move through the items.
API-based carousel using Django
Below is the step-by-step implementation of an API-based carousel using Django In Python.
To install Django follow these steps.
Starting the Project Folder
To start the project, and app use this command
django-admin startproject carousel
cd carousel
python manage.py startapp carousel_project
Now add this app to the ‘settings.py’
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"carousel",
]
File Structure

Setting Necessary Files
models.py: Below, code creates a Django model, `CarouselItem`, representing carousel items with title, image URL, and description fields. The `__str__` method defines the string representation as the item's title.
Python3
from django.db import models
class CarouselItem(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=255)
image_url = models.URLField()
description = models.TextField()
def __str__(self):
return self.title
serializers.py : Below, code creates a Django REST Framework serializer, `CarouselItemSerializer`, for the `CarouselItem` model with specified fields, enabling easy conversion between JSON and model instances for API interactions.
Python3
from rest_framework import serializers
from .models import CarouselItem
class CarouselItemSerializer(serializers.ModelSerializer):
class Meta:
model = CarouselItem
fields = ['id','title', 'image_url', 'description']
views.py : Below, code defines Django views for rendering HTML templates and two Django REST Framework API views (`CarouselItemList` and `CarouselItemDetail`). The views handle list and creation operations as well as retrieve, update, and delete operations for the `CarouselItem` model. The corresponding HTML templates are for carousel display, form submission, and item list/update.
Python3
from rest_framework import status
from rest_framework.response import Response
from rest_framework import generics
from django.shortcuts import render
from .models import CarouselItem
from .serializers import CarouselItemSerializer
def carousel_view(request):
return render(request, 'carousel/index.html')
def carousel_Form_view(request):
return render(request, 'carousel/form.html')
def carousel_update_delete(request):
return render(request, 'carousel/list.html')
def carousel_update(request, pk):
return render(request, 'carousel/update.html')
class CarouselItemList(generics.ListCreateAPIView):
queryset = CarouselItem.objects.all()
serializer_class = CarouselItemSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class CarouselItemDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = CarouselItem.objects.all()
serializer_class = CarouselItemSerializer
lookup_field = 'pk' # Use 'id' as the lookup field
carousel/urls.py :Below, code sets up Django URL patterns linking specific URLs to corresponding views for a carousel application. It includes paths for index, form, list, update, and API endpoints for item retrieval and details.
Python3
from django.urls import path
from . import views
urlpatterns = [
path('index/', views.carousel_view, name='index'),
path('', views.carousel_Form_view, name='form'),
path('list/', views.carousel_update_delete, name='list'),
path('update/<int:pk>/', views.carousel_update, name='update'),
path('api/', views.CarouselItemList.as_view(), name='carousel-item-list'),
path('api/<int:pk>/', views.CarouselItemDetail.as_view(), name='carousel-item-detail'),
]
carousel_project/urls.py : The code configures Django URL patterns, linking 'admin/' to the admin interface and including URLs from the 'carousel.urls' module at the root level ('').
Python3
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('carousel.urls')),
]
Creating GUI ( templates/carousel)
form.html : Below, HTML code is a Bootstrap-styled form for creating a new carousel item. It uses JavaScript for client-side validation and includes a `postData` function to send a POST request to the API endpoint ('http://127.0.0.1:8000/api/') with entered data. The CSRF token is included for security, and there's a 'See Carousel' button to reload the page after form submission.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Create Carousel Item</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div class="container mt-5">
<h2>Create Carousel Item</h2>
<form id="carouselForm">
<div class="form-group">
<label for="title">Title:</label>
<input type="text" class="form-control" id="title" name="title" required>
<div class="invalid-feedback">Title is required.</div>
</div>
<div class="form-group">
<label for="image_url">Image URL:</label>
<input type="text" class="form-control" id="image_url" name="image_url" required>
<div class="invalid-feedback">Image URL is required.</div>
</div>
<div class="form-group">
<label for="description">Description:</label>
<textarea class="form-control" id="description" name="description" required></textarea>
<div class="invalid-feedback">Description is required.</div>
</div>
<button type="button" class="btn btn-primary" onclick="postData()">Submit</button>
<a href="{% url 'index' %}" type="button" class="btn btn-success" onclick="postData()">See Carousel</a>
</form>
</div>
<!-- Bootstrap JS and dependencies -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script>
function postData() {
// Validate the form
if (validateForm()) {
let title = document.getElementById('title').value;
let image_url = document.getElementById('image_url').value;
let description = document.getElementById('description').value;
const data = {
title: title,
image_url: image_url,
description: description
};
fetch('http://127.0.0.1:8000/api/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': getCookie('csrftoken') // Ensure to include CSRF token
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
console.log('Success:', result);
})
.catch(error => {
console.error('Error:', error);
// Handle errors as needed
});
}
location.reload();
// Return false to prevent the form from being submitted
return false;
}
function validateForm() {
const title = document.getElementById('title').value;
const image_url = document.getElementById('image_url').value;
const description = document.getElementById('description').value;
const invalidFeedbacks = document.querySelectorAll('.invalid-feedback');
invalidFeedbacks.forEach(element => {
element.style.display = 'none';
});
let isValid = true;
if (!title.trim()) {
document.getElementById('title').nextElementSibling.style.display = 'block';
isValid = false;
}
if (!image_url.trim()) {
document.getElementById('image_url').nextElementSibling.style.display = 'block';
isValid = false;
}
if (!description.trim()) {
document.getElementById('description').nextElementSibling.style.display = 'block';
isValid = false;
}
return isValid;
}
// Function to get CSRF token from cookies
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
</script>
</body>
</html>
index.html : Below HTML template utilizes Bootstrap to create a visually appealing image carousel. It includes JavaScript to fetch data from an API ('http://127.0.0.1:8000/api/') and dynamically updates the carousel with the retrieved items. The template also features buttons for adding images and updating/deleting slides, with links to specific URLs. Custom styles are applied to the carousel, images, and buttons for a polished appearance.
HTML
<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous" />
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script>
// Assume this script is in a separate JavaScript file linked to your HTML
document.addEventListener('DOMContentLoaded', function () {
// Fetch data from the API
fetch('http://127.0.0.1:8000/api/')
.then((response) => response.json())
.then((data) => {
// Select the carousel container element
const carouselContainer = document.querySelector('.carousel-inner')
// Iterate over the fetched data and update the carousel
data.forEach((item) => {
console.log(item)
let code = ` <div class="carousel-item">
<img id="imgSlide" class="d-block w-100" src="${item.image_url}" alt="${item.title}" />
<div class="carousel-caption d-none d-md-block">
<h5>${item.title}</h5>
<p>${item.description}</p>
</div>
</div>`
carouselContainer.innerHTML += code;
})
})
.catch((error) => console.error('Error fetching data:', error))
})
</script>
<title>carousel</title>
<style>
/* Custom Carousel Styles */
#carouselExampleIndicators {
margin-top: 20px;
}
#imgSlide {
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
height: 400px; /* Set a fixed height for the images */
object-fit: cover; /* Adjust the object-fit property as needed */
}
.carousel-caption {
background-color: rgba(0, 0, 0, 0.5);
border-radius: 5px;
padding: 10px;
}
.carousel-caption h5,
.carousel-caption p {
color: #fff;
margin: 0;
}
/* Centered Heading */
#devnamdev {
margin-top: 30px;
}
/* Buttons Styling */
.btn-info,
.btn-success {
margin-top: 15px;
}
/* Custom Carousel Styles */
#carouselExampleIndicators {
margin-top: 20px;
}
#imgSlide {
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.carousel-caption {
background-color: rgba(0, 0, 0, 0.5);
border-radius: 5px;
padding: 10px;
}
.carousel-caption h5,
.carousel-caption p {
color: #fff;
margin: 0;
}
/* Centered Heading */
#devnamdev {
margin-top: 30px;
}
/* Buttons Styling */
.btn-info,
.btn-success {
margin-top: 15px;
}
</style>
</head>
<body>
<h1 id="devnamdev" style="text-align: center; color: green; font-family: 'Times New Roman', Times, serif;">GeeksforGeeks</h1>
<h2 id="devnamdev" style="text-align: center;">carousel</h2>
<div class="container">
<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img id="imgSlide" class="d-block w-100" src="https://source.unsplash.com/1080x460/?flower" alt="Flower" />
<div class="carousel-caption d-none d-md-block">
<h5>Flower</h5>
</div>
</div>
</div>
<a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
<div class="mt-3 container">
<a href="{% url 'form' %}" class="btn btn-info">Add Image</a>
<a href="/list" class="btn btn-success">Update/Delete Slide</a>
</div>
</body>
</html>
list.html : Below, HTML template displays a table of carousel items with titles. It fetches data from the '/api' endpoint using JavaScript and dynamically populates the table. Each row includes buttons for updating and deleting the respective item. The 'Back' button links to the 'index' URL. The JavaScript functions handle item deletion and navigation to the update form.
HTML
<!-- carousel/templates/carousel/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Carousel Items</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
<h2>Carousel Items</h2>
<table class="table mt-3" id="carouselTable">
<thead>
<tr>
<th>Title</th>
<!-- Add other fields as needed -->
<th>Actions</th>
</tr>
</thead>
<tbody id="carouselBody">
<!-- Data will be dynamically inserted here -->
</tbody>
</table>
<hr>
<a href="{% url 'index' %}" type="button" class="btn btn-warning" >Back</a>
</div>
<script>
// Fetch and display data on page load
document.addEventListener('DOMContentLoaded', function () {
fetchData();
});
// Function to fetch and display data
function fetchData() {
fetch('/api')
.then(response => response.json())
.then(data => {
const tableBody = document.getElementById('carouselBody');
tableBody.innerHTML = '';
data.forEach(item => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${item.title}</td>
<td>
<button class="btn btn-primary btn-sm" onclick="updateItem(${item.id})">Update</button>
<button class="btn btn-danger btn-sm" onclick="deleteItem(${item.id})">Delete</button>
</td>
`;
tableBody.appendChild(row);
});
})
.catch(error => console.error('Error fetching data:', error));
}
// Function to delete an item
function deleteItem(itemId) {
if (confirm("Are you sure you want to delete this item?")) {
fetch(`/api/${itemId}/`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': '{{ csrf_token }}',
},
})
.then(response => {
if (response.ok) {
fetchData(); // Refresh the data after deletion
} else {
alert("Failed to delete item.");
}
})
.catch(error => console.error('Error deleting item:', error));
}
}
// Function to navigate to the update form
function updateItem(itemId) {
window.location.href = `/update/${itemId}/`;
}
</script>
</body>
</html>
update.html : Below, HTML template serves as an update form for a carousel item. It uses Bootstrap for styling and JavaScript to fetch the item data from the API, pre-fill the form fields, and handle form submission with a PUT request to update the item. Upon successful update, it displays an alert and redirects to the 'list' page.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Update Carousel Item</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" />
</head>
<body>
<div class="container mt-5">
<h2>Update Carousel Item</h2>
<form id="updateForm">
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" required />
<label for="link">URL</label>
<input type="text" class="form-control" id="image_url" name="image_url" required />
<label for="description">Description</label>
<input type="text" class="form-control" id="description" name="description" required />
</div>
<!-- Add other form fields as needed -->
<button type="submit" class="btn btn-primary">Update</button>
</form>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
// Fetch item data and fill the form fields
const url = window.location.pathname.split('/')
let itemId = url[2]
fetch(`/api/${itemId}/`)
.then((response) => response.json())
.then((data) => {
document.getElementById('title').value = data.title
document.getElementById('image_url').value = data.image_url
document.getElementById('description').value = data.description
// Set values for other form fields as needed
})
.catch((error) => console.error('Error fetching item data:', error))
// Submit form with API call
document.getElementById('updateForm').addEventListener('submit', function (event) {
event.preventDefault()
// Get form data
const formData = new FormData(this)
// Make API call to update item
fetch(`/api/${itemId}/`, {
method: 'PUT',
headers: {
'X-CSRFToken': '{{ csrf_token }}'
},
body: formData
})
.then((response) => response.json())
.then((data) => {
alert('Item updated successfully!')
window.location.href = '/list'
})
.catch((error) => console.error('Error updating item:', error))
})
})
</script>
</body>
</html>
admin.py : In admin we register the model.
Python3
from django.contrib import admin
from .models import CarouselItem
class CarouselItemAdmin(admin.ModelAdmin):
list_display = ('id','title', 'image_url', 'description')
search_fields = ('title', 'description')
admin.site.register(CarouselItem, CarouselItemAdmin)
Deployement of the Project
Run these commands to apply the migrations:
python3 manage.py makemigrations
python3 manage.py migrate
Run the server with the help of following command:
python3 manage.py runserver
Output

Video Demonstration
Similar Reads
How to Create a basic API using Django Rest Framework ? Django REST Framework (DRF) is a powerful extension of Django that helps you build APIs quickly and easily. It simplifies exposing your Django models as RESTfulAPIs, which can be consumed by frontend apps, mobile clients or other services.Before creating an API, there are three main steps to underst
4 min read
How to Add Cart in a Web Page using Django? A shopping cart allows users to collect and manage items they want to purchase before proceeding to checkout. We will build a simple shopping cart using Django and learn how to create models, views, templates and URLs to add, view and remove items from the cartâstep by step.Create Django Project and
6 min read
How to Create a Basic Project using MVT in Django ? Prerequisite - Django Project MVT Structure Assuming you have gone through the previous article. This article focuses on creating a basic project to render a template using MVT architecture. We will use MVT (Models, Views, Templates) to render data to a local server. Create a basic Project: To in
2 min read
How to make multi item carousel using Bootstrap 5 We will learn how to implement a multi-item carousel using Bootstrap 5. The carousel component in Bootstrap 5 provides a user-friendly way to display a rotating set of content, such as images or text, in a sliding manner. This feature is commonly used for showcasing products, portfolios, or any cont
3 min read
How To Integrate Ajax with Django Applications Django is one of the most popular web frameworks for building robust and scalable web applications. However, many modern applications require asynchronous features, enabling real-time interactions without the need to reload the entire page. This is where Ajax (Asynchronous JavaScript and XML) comes
5 min read
How to create a form using Django Forms ? This article explains how to create a basic form using various form fields and attributes. Creating a form in Django is very similar to creating a model, you define the fields you want and specify their types. For example, a registration form might need fields like First Name (CharField), Roll Numbe
2 min read
Creating a JSON Response Using Django and Python In Django, we can give responses to the front end in several ways. The simplest way to render a template or send a JSON response. JSON stands for JavaScript Object Notation and is widely used for data transfer between front-end and back-end and is supported by different languages and frameworks. In
4 min read
Joke Application Project Using Django Framework We will create a simple Joke application using Django. By using the pyjokes package, weâll build a web app that generates and displays random jokes. Weâll go step-by-step to set up the project, configure the views, and render jokes dynamically on the homepage.Install Required PackagesFirst, install
2 min read
How to Create a Carousel in Bootstrap ? Carousels are commonly used to showcase multiple images or content dynamically and interactively. It provides a convenient way to implement carousels with built-in functionality and styles. Approach:Create an HTML document with Bootstrap 5 library classes for styling.Create a container with a center
2 min read
Browsable API in Django REST Framework The browsable API feature in the Django REST framework generates HTML output for different resources. It facilitates interaction with RESTful web service through any web browser. To enable this feature, we should specify text/html for the Content-Type key in the request header. It helps us to use we
8 min read