18. Add and remove products on cart
Now we will implement the functionality to add and remove products from our cart.
Adding a product
We will modify the add_to_cart
function inside views.py
to enable the addition of a product via the HTML form. The results are explained below:
if request.user.is_authenticated:
client = request.user.client
else :
return redirect('store')
order, created = Order.objects.get_or_create(client=client, finished=False)
item_stock = ItemStock.objects.get(product__id=product_id, size=size, color=color_id) #? In the forms we enter the color, id, and the size
item_ordered, created = OrderedItem.objects.get_or_create(order=order, itemstock=item_stock) #? adding the product to the cart
item_ordered.quantity += 1
item_ordered.save() #? Must save changes made directly to a element
User Authentication Check: The code first verifies if the user is authenticated. If not, it redirects the user to the store page.
Retrieve or Create Order: If the user is authenticated, it retrieves the client's current order that is not finished. If no such order exists, a new one is created.
Fetch ItemStock: The specific item to be added is fetched from the
ItemStock
table using the provided product ID, size, and color (those specific parameters were used as they are also the ones being used on the form).Add or Update OrderedItem: It then adds this item to the order by either updating an existing
OrderedItem
or creating a new one.Increment Quantity: The quantity of the item in the order is incremented, and the changes are saved to the database (as changes made directly to the element of a class must be saved).
Modifying product quantity
Currently, we can only add one product at a time to the cart. To change this, we will add plus and minus buttons alongside the displayed quantity on the forms, allowing the user to choose the number of each product they want to add to the car
We will update the cart.html
file by integrating buttons using the <form>
tag. This approach is consistent with the methodology previously applied to implement the "add to cart" button.
<img src="{{ item.itemstock.product.image.url }}" width = "60" height = "80">
Product: {{ item.itemstock.product.name }};
Color: {{ item.itemstock.color.name }};
Size: {{ item.itemstock.size }};
<div style="display:flex;"> <!--Makes eveyrything in the same line-->
Quantity:
<!--! REMOVE BUTTON -->
<form method = "POST" action = "{% url 'remove_from_cart' item.itemstock.product.id %}"> <!--? Changed the product reference to the one being used in the code above-->
{% csrf_token %} <!--Protects (by generating a unique token) the forms from hackers trying to replicate it-->
<input type="hidden" name="size" value="{{ item.itemstock.size }}">
<input type="hidden" name="color" value="{{ item.itemstock.color.id }}">
<button type="submit">-</button>
</form>
{{ item.quantity}}
<!--! ADD BUTTON -->
<form method = "POST" action = "{% url 'add_to_cart' item.itemstock.product.id %}"> <!--? Changed the product reference to the one being used in the code above-->
{% csrf_token %} <!--Protects (by generating a unique token) the forms from hackers trying to replicate it-->
<input type="hidden" name="size" value="{{ item.itemstock.size }}">
<input type="hidden" name="color" value="{{ item.itemstock.color.id }}">
<button type="submit">+</button>
</form>;
</div>
Unit Price: {{ item.itemstock.product.price }};
Total Price: R${{ item.total_price }}
</p>
<hr> <!--Horizonal row-->
The modifications include the following:
Encapsulated Button Code: All button-related code is now enclosed within a
<div>
tag with adisplay: flex
style. This layout ensures that the buttons appear adjacent to the quantity amount, enhancing the user interface. Further aesthetic improvements will be addressed later in the project.Action Attributes: Incorporated the
remove_from_cart
andadd_to_cart
URLs into the respectiveaction
attributes of the<form>
elements.Button Elements: Added the buttons using the
<button>
tag.Visual Separation: Included a horizontal line using the
<hr>
tag to provide visual separation within the page.
In the views.py
file, we will create a remove_from_cart
function. To achieve this, we will copy the code from the add_to_cart
function and make the necessary adaptations.
def remove_from_cart(request, product_id) :
if request.method == "POST" and product_id : #? if the user is sending a new product
data = request.POST.dict() #? converts the request data to a dictionary
size = data.get('size') #? used get instead of ['size] as it wont return a error
color_id = data.get('color')
if not size:
return redirect('store')
#!getting the client
if request.user.is_authenticated:
client = request.user.client
else :
return redirect('store')
order, created = Order.objects.get_or_create(client=client, finished=False)
item_stock = ItemStock.objects.get(product__id=product_id, size=size, color=color_id) #? In the forms we enter the color, id, and the size
item_ordered, created = OrderedItem.objects.get_or_create(order=order, itemstock=item_stock) #? adding the product to the cart
item_ordered.quantity -= 1 #? only difference is that we are removing a item from the cart
item_ordered.save() #? Must save changes made directly to a element
if item_ordered.quantity <= 0 :
item_ordered.delete()
return redirect('cart')
else :
return redirect('store') #? redirect the user to the store if he didn't choose a product
The adaptations made include:
Quantity Adjustment: Modified the operation from
+= 1
to-= 1
foritem_ordered.quantity
to reflect the removal of an item.Conditional Removal: Added an
if
condition to check ifitem_ordered.quantity
is less than or equal to 0. If true, the item is removed from the cart list entirely.
Finally, we will add the new remove_from_cart
URL to the list of URLs in the urls.py
file to ensure proper routing of the remove-from-cart functionality.
path('removefromcart/<int:product_id>/', remove_from_cart, name="remove_from_cart"),
Upon running the site, users can now effectively add and remove items from the cart using the buttons. The cart data, including the total price, dynamically updates to reflect these changes in real-time.

Last updated