So, I am developing a cart system for an e-commerce website using Django. There are two separate functions for handling adding and removing cart items. (No I can't consolidate them into one function without changing my database and template structure)
The first function, 'update_cart' is working just fine. It properly updates the appropriate model.
However, the second function 'remove_item' is triggered when the user clicks the 'remove' button in the item list, and the function does in fact execute and redirect properly.
However, it fails to update the many-to-many, foreign key-identified model object associated with the item.
It's so weird because I'm accessing the object the same way in both functions. The only difference is that in the first uses .add() and the second .remove().
Also, the template is supposed to load the product's id into the GET data but doesn't show it in the URL like with the other template that triggers the 'update_cart' function.
But it does show the mycart/?id=86 when the cursor is hovering over the button. (this is a chrome feature). It's very confusing.
Can you guys help me to see what I am overlooking? Thanks for your time. :)
view.py functions:
def update_cart(request):
context={}
if request.user.is_authenticated:
print('triggered')
owner = request.user.id
cart = Cart.objects.get(cart_owner=owner)
productID = request.GET['id']
product = Product.objects.get(pk=productID)
cart.products.add(product)
new_total = 0.00
for item in cart.products.all():
new_total += float(item.priceNotax)
cart.total = new_total
cart.save()
def remove_item(request):
if request.user.is_authenticated:
owner = request.user.id
cart = Cart.objects.get(cart_owner=owner)
productID = request.GET['id']
print(productID)
product = Product.objects.get(pk=productID)
cart.products.remove(product)
cart.save()
new_total = 0.00
for item in cart.products.all():
new_total += float(item.priceNotax)
cart.total = new_total
cart.save()
return HttpResponseRedirect(reverse("myCart"))
else:
return HttpResponseRedirect(reverse("login"))
The model.py file containing the affected 'Cart' model:
class Cart(models.Model):
cart_owner = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
products = models.ManyToManyField(Product, null=True, blank=True)
#held_items = models.ManyToManyField(Order_holding, null=True, blank=True)
total = models.DecimalField(max_digits=100, decimal_places=2, default=0.00)
timestamp = models.DateTimeField(auto_now_add=False, auto_now=True)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
active = models.BooleanField(default=True)
def __unicode__(self):
return "Cart id: %s" %(self.id)
The template that triggers the 'remove_item' function:
{% extends 'base.html' %}
{% load static %}
{% block content %}
<div class="container-fluid mb-2">
<div class="card">
<div class="card-header"><h3>Shopping Cart</h3></div>
</div>
</div>
{% for item in cart.products.all %}
<div class="container-fluid mb-2">
<div class=".row-4 .row-sm-4 m-4 card justify-content-center">
<div><h4>{{ item.name }}</h4></div>
<div><h4>Price: ${{ item.priceNotax }}</h4><a href="{% url 'remove_item'%}?id={{item.id}}"><button class='btn-danger justify-content-right'>Remove</button></div></a>
</div>
</div>
{% endfor %}
<h2>Sub-Total: ${{total}}</h2>
<a href="{% url 'products'%}"><button class="btn-primary">Continue Shoping</button></a>
{% endblock content %}
# urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls import patterns, include, url
from django.conf.urls.static import static
from cart.views import addToCart, update_cart
from products.views import productsPage
from products import urls admin.autodiscover()
from . import views
urlpatterns = [ path('myCart/', views.myCart,name='myCart'),
path('products/', views.productsPage,name='products'),
path('addToCart/', update_cart, name='update_cart'),
]