In this Python tutorial, I will show how to add items to cart in Django where you will understand how to implement the cart functionality to add or remove the items to cart.
So here I will continue with the previous Django application where you learned how to create a user profile in Django, you can refer to that tutorial How to Create a User Profile Using Django.
So first go through that tutorial, then follow this one to add the cart functionality. Additionally, I will show you how to increase or decrease the quantity of already added items to the cart and also how to remove the items from the cart.
How to Add Items to Cart In Django
Create a model Product in the model.py of your Django app ‘profile_app’ using the below code.
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
image = models.URLField()
def __str__(self):
return self.name
Also, add the Cart and Cart_Item models to the model.py file of your Dajngo app ‘profile_app’.
class CartItem(models.Model):
cart = models.ForeignKey('Cart', on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=1)
def __str__(self):
return f"{self.quantity} x {self.product.name}"
class Cart(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
products = models.ManyToManyField(Product, through='CartItem')
def __str__(self):
return f"Cart for {self.user.username}"
User.profile = property(lambda u: Profile.objects.get_or_create(user=u)[0])
User.cart = property(lambda u: Cart.objects.get_or_create(user=u)[0])
Create a view ‘product_list’ in the views.py of your Dajngo app ‘profile_app’ using the below code.
def product_list(request):
products = Product.objects.all()
return render(request, 'product_list.html', {'products': products})
The product_list view fetches all the product data using the Product.objects.all() as quest and assigns to variable products, then the products are passed to a template ‘product_list.html’ as context.
After creating the product_list view, create a new template ‘product_list.html’ in the templates folder of your Django app and add the following code.
{% extends "home.html" %}
{% load static %}
{% block content %}
<link rel="stylesheet" href="{%static 'css/product_list.css' %}">
<h1>Product List</h1>
{% for product in products %}
<div class="product-card">
<div class="product-image">
<img src="{{ product.image }}" alt="{{ product.name }}">
</div>
<div class="product-name">{{ product.name }}</div>
<div class="product-description">{{ product.description }}</div>
<div class="product-price">$ {{ product.price }}</div>
<form action="{% url 'add-to-cart' product.id %}" method="post">
{% csrf_token %}
<button class="add-to-cart-btn">Add to Cart</button>
</form>
</div>
{% endfor %}
{% endblock %}
The above template takes the product data which is passed as the context and shows all the products with product images, names, descriptions, and prices.
To render the data from the context ‘product’, use the variable within nested curly braces {{ varibale}} such as to render the name of the product, use {{ product.name }} and so on for other product information.
Also, the template contains the add to cart button to add the specific product to the cart.
Now add the functionality of adding or removing products to the cart, and view the cart items, so for that follow the below steps:
Create the view add_to_cart in the views.py file of your Django app by adding the following code.
from .models import Product, Cart, CartItem
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
@login_required(login_url='login')
def add_to_cart(request, product_id):
product = Product.objects.get(pk=product_id)
cart, created = Cart.objects.get_or_create(user=request.user)
cart_item, item_created = CartItem.objects.get_or_create(cart=cart, product=product)
if not item_created:
cart_item.quantity += 1
cart_item.save()
return redirect('product-list')
The view add_to_cart fetches the specific product based on the provided product_id from the database using the Product.objects.get(pk=product_id).
- Then next line 123 in the above picture, retrieve the user cart from the database using the (cart, created = Cart.objects.get_or_create(user=request.user)), if the cart exists, then it is retrieved, otherwise, a new cart is created for that user, then assigned to a variable cart. The variable ‘created’ tells whether newly cart was created.
- next line 124, receives the cart item from the database using the (cart_item, item_created = CartItem.objects.get_or_create(cart=cart, product=product)). Then cart and product are associated with the cart item. If a cart item for the given cart and product exists, it is retrieved. If not, a new cart item is created.
- The variable ‘item_created’ tells whether newly cart item was created. Then the line number from 126 to 128, checks if the cart item was not newly created using (if not item_created) which means the cart item already existed and the user is adding a duplicate product to the cart.
- So the quantity of the cart item is increased by one and saved to the database.
Then create a view remove_from_cart by adding the following code.
@login_required(login_url='login')
def remove_from_cart(request, product_id):
product = Product.objects.get(pk=product_id)
cart = Cart.objects.get(user=request.user)
try:
cart_item = cart.cartitem_set.get(product=product)
if cart_item.quantity >= 1:
cart_item.delete()
except CartItem.DoesNotExist:
pass
return redirect('cart')
The above view remove_from_cart removes the item from the cart based on the provided porduct_id.
- The code at line number 134, receives the product object from the database using the Product.objects.get(pk=product_id) method and assigns it a variable product. Then in the next line, retrieve the user cart from the database using Cart.objects.get(user=request.user) and assign it a variable cart.
- At line number 137, retrieve the particular cart item from the user’s cart using (cart.cartitem_set.get(product=product) )and assign it to a variable cart_item. Then check the cart item quantity, if the quantity is greater than or equal to 1, it removes or deletes the cart item from the cart using cart_item.delete().
Also, add the view ‘view_cart’ to view all the items of the cart, so add the following code.
@login_required(login_url='login')
def view_cart(request):
cart = request.user.cart
cart_items = CartItem.objects.filter(cart=cart)
return render(request, 'cart.html', {'cart_items': cart_items})
The view view_cart retrieves all the cart items from the user cart. Line number 147, retrieves the user cart using the request.user.cart and assigns it to the variable cart.
- Then in the next line 148, retrieve all the cart items from the user cart using the cart_items = CartItem.objects.filter(cart=cart) and assign it to variable cart_items. Then all the cart items are passed as context to the template ‘cart.html’.
Finally, add the two views named ‘increase_cart_item’ and ‘decrease_cart_item’ to increase or decrease the quantity of the items in the cart respectively.
@login_required(login_url='login')
def increase_cart_item(request, product_id):
product = Product.objects.get(pk=product_id)
cart = request.user.cart
cart_item, created = CartItem.objects.get_or_create(cart=cart, product=product)
cart_item.quantity += 1
cart_item.save()
return redirect('cart')
@login_required(login_url='login')
def decrease_cart_item(request, product_id):
product = Product.objects.get(pk=product_id)
cart = request.user.cart
cart_item = cart.cartitem_set.get(product=product)
if cart_item.quantity > 1:
cart_item.quantity -= 1
cart_item.save()
else:
cart_item.delete()
return redirect('cart')
Now create a template cart.html in the templates folder of your Django app ‘profile_app’ by adding the following code in that file.
{% extends "home.html" %}
{% load static %}
{% block content %}
<link rel="stylesheet" href="{% static 'css/cart.css' %}">
<div class="container">
<div class="cart-header">
<h1>Your Cart</h1>
</div>
<ul>
{% for item in cart_items %}
<li class="cart-item">
<div class="cart-item-details">
<div class="cart-item-name">{{ item.product.name }}</div>
<form action="{% url 'remove-from-cart' item.product.id %}" method="post">
{% csrf_token %}
<button class="remove-from-cart-btn" type="submit">Remove</button>
</form>
</div>
<div class="cart-item-quantity">
<form action="{% url 'increase-cart-item' item.product.id %}" method="post">
{% csrf_token %}
<button class="quantity-btn increase-quantity" type="submit">+</button>
</form>
<span class="item-quantity">{{ item.quantity }}</span>
<form action="{% url 'decrease-cart-item' item.product.id %}" method="post">
{% csrf_token %}
<button class="quantity-btn decrease-quantity" type="submit">-</button>
</form>
</div>
<div class="cart-item-price" data-price="{{ item.product.price }}">
${{ item.product.price }}
</div>
</li>
{% endfor %}
</ul>
<a class="continue-shopping-link" href="{% url 'product-list' %}">Continue Shopping</a>
<a class="checkout-button" href="#">Checkout</a>
</div>
<script src="{% static 'js/cart.js' %}"></script>
{% endblock %}
Set up the URLs for the views that you have created, so open the urls.py file of your Django app and add the following URL path.
path('product-list/', product_list, name='product-list'),
path('add-to-cart/<int:product_id>/', add_to_cart, name='add-to-cart'),
path('remove-from-cart/<int:product_id>/', remove_from_cart, name='remove-from-cart'),
path('cart/', view_cart, name='cart'),
path('increase-cart-item/<int:product_id>/', increase_cart_item, name='increase-cart-item'),
path('decrease-cart-item/<int:product_id>/', decrease_cart_item, name='decrease-cart-item'),
Then add styling to the template ‘product_list.html’ and ‘cart.html’, for that create two files ‘product_list.css’ and ‘cart.css’ within css folder of the static directory of your project.
In the product_list.css add the following style code.
.product-card {
border: 1px solid #ccc;
border-radius: 8px;
padding: 16px;
margin: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
display: inline-block;
vertical-align: top;
width: 240px;
background: white;
}
.product-image img {
max-width: 100%;
height: auto;
margin-bottom: 12px;
}
.product-name {
font-size: 18px;
font-weight: bold;
margin-bottom: 8px;
}
.product-description {
font-size: 14px;
margin-bottom: 8px;
}
.product-price {
font-size: 16px;
font-weight: bold;
color: #007bff;
}
.add-to-cart-btn {
background-color: #007bff;
color: #fff;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
In ‘cart.css’ add these codes.
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f4f4f4;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.cart-header {
text-align: center;
margin-bottom: 20px;
}
.cart-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid #ddd;
}
.cart-item-details {
display: flex;
align-items: center;
}
.cart-item-name {
font-weight: bold;
margin-right: 10px;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.remove-from-cart-btn,
.quantity-btn {
background-color: #ff6347;
color: white;
border: none;
border-radius: 4px;
padding: 5px 10px;
cursor: pointer;
transition: background-color 0.3s;
}
.remove-from-cart-btn:hover,
.quantity-btn:hover {
background-color: #e74c3c;
}
.cart-item-quantity {
display: flex;
align-items: center;
margin-right: 10px;
}
.cart-item-price {
font-weight: bold;
}
.continue-shopping-link {
display: inline-block;
margin-top: 20px;
text-decoration: none;
color: #3498db;
font-weight: bold;
}
.continue-shopping-link:hover {
text-decoration: underline;
}
.checkout-button {
display: inline-block;
background-color: #28a745;
color: white;
padding: 10px 20px;
border-radius: 4px;
margin-top: 20px;
margin-left: 400px;
text-decoration: none;
font-weight: bold;
transition: background-color 0.3s;
}
.checkout-button:hover {
background-color: #218838;
}
Lastly, add a view ‘fetch_cart_count’ to count the items in the user cart and a function ‘get_cart_count’ to compute the number of items in the user cart.
Add the view ‘fetch_cart_count’ in the views.py file of your Django app.
@login_required(login_url='login')
def fetch_cart_count(request):
cart_count = 0
if request.user.is_authenticated:
cart = request.user.cart
cart_count = CartItem.objects.filter(cart=cart).count()
return JsonResponse({'cart_count': cart_count})
Then add the function ‘get_cart_count’ using the below code.
def get_cart_count(request):
if request.user.is_authenticated:
cart_items = CartItem.objects.filter(cart=request.user.cart)
cart_count = cart_items.count()
else:
cart_count = 0
return cart_count
Add the URLs for the view fetch_cart_count by adding the following path in the urls.py of your Django app ‘profile_app’.
path('fetch-cart-count/', fetch_cart_count, name='fetch-cart-count'),
Create a new file called cart.js and add it to the js folder of the static directory and leave it empty now. Then open the file script.js within folder js of the static directory and the function updateCartCount(), this function updates the cart items as soon as they are added by the user.
function updateCartCount() {
var cartCount = document.querySelector('.cart-count');
fetch('{% url "fetch-cart-count" %}')
.then(response => response.json())
.then(data => {
cartCount.textContent = data.cart_count;
});
}
updateCartCount();
Also, add the following code to the cart.js file.
const increaseButtons = document.querySelectorAll(".increase-quantity");
const decreaseButtons = document.querySelectorAll(".decrease-quantity");
const quantityElements = document.querySelectorAll(".item-quantity");
const priceElements = document.querySelectorAll(".cart-item-price");
increaseButtons.forEach((button, index) => {
button.addEventListener("click", (event) => {
event.preventDefault();
const currentItem = event.target.closest(".cart-item");
const quantityElement = currentItem.querySelector(".item-quantity");
const priceElement = currentItem.querySelector(".cart-item-price");
const pricePerItem = parseFloat(priceElement.getAttribute("data-price"));
const currentQuantity = parseInt(quantityElement.textContent);
quantityElement.textContent = currentQuantity + 1;
updateCartItemPrice(priceElement, pricePerItem, currentQuantity + 1);
});
});
decreaseButtons.forEach((button, index) => {
button.addEventListener("click", (event) => {
event.preventDefault();
const currentItem = event.target.closest(".cart-item");
const quantityElement = currentItem.querySelector(".item-quantity");
const priceElement = currentItem.querySelector(".cart-item-price");
const pricePerItem = parseFloat(priceElement.getAttribute("data-price"));
const currentQuantity = parseInt(quantityElement.textContent);
if (currentQuantity > 1) {
quantityElement.textContent = currentQuantity - 1;
updateCartItemPrice(priceElement, pricePerItem, currentQuantity - 1);
}
});
});
function updateCartItemPrice(priceElement, pricePerItem, quantity) {
const totalPrice = (pricePerItem * quantity).toFixed(2);
priceElement.textContent = "$" + totalPrice;
}
Then update the home.html file for showing the cart icon with value, so add the following code.
{% if user.is_authenticated %}
<div class="cart-icon">
<a href="{% url 'cart' %}" class="view-cart-link">
<img src="{% static 'images/cart.png' %}" alt="Cart">
</a>
{% if cart_count == 0 %}
<span></span>
{% else %}
<span class="cart-count">{{ cart_count }}</span>
{% endif %}
Also, open the home.css file and add the following style for the cart icon.
.cart-icon {
position: relative;
display: inline-block;
}
.cart-count {
position: absolute;
top: -8px;
right: -8px;
background-color: red;
color: white;
border-radius: 50%;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
}
Now register the created model in the admin.py file of the Django app ‘profile_app’ by adding the following line of code.
from django.contrib import admin
from .models import Profile, Product, Cart, CartItem
admin.site.register(Profile)
admin.site.register(Product)
admin.site.register(CartItem)
admin.site.register(Cart)
Run the below command one by one in your terminal.
python manage.py makemigrations
python manage.py migrate
Then run the server using the below command.
python manage.py runserver
Then open the URL ‘http://127.0.0.1:8000/login/’ and log in with your username and password, if you haven’t created it, then create a new one by clicking on the Register button at the top.
After login, a page appears, and your page background may appear in a different color, then click on the Products link in the navigation menu.
Then click on the button Add to Cart to add the product to the cart.
You can also increase or decrease the product quantity by clicking on the plus (+) and minus (-) buttons as shown below.
Remove one of the items from the cart by clicking on the button Remove.
Now you have successfully implemented the adding items to the cart in Django.
Conclusion
In this Python tutorial, you learned how to implement the cart functionality in Django, where you create the product list page to show the product with add to cart button. Then added the cart icon in the navigation menu to show the number of items in the current user cart. Also, create a page where users can view or remove the existing items from the cart.
You may like to read:
- JWT Authentication Using Django Rest Framework
- How to Create Card with Button in Django
- Payment Gateway Integration with Django
I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.