Reputation: 994
I'm trying to create a function to empty all of the items from my cart in sessions. I have a perfectly good function that removes individual item, but can't get it to work for all. Can you let me know what I'm doing wrong? Thanks! I've tried to create the following function:
cart.py
class Cart(object):
...
def clear(self):
self.session.cart[settings.CART_SESSION_KEY] = {}
self.session.modified = True
Called it in my url/views/template like:
urls.py
path('cart/clear/', Buylist_views.clear, name= 'empty_cart'),
views.py
def clear(request):
cart = Cart(request)
cart.clear()
return redirect('cart')
template
...
<button type="submit" formaction="{% url 'empty_cart' %}">
Empty Cart </button>
</form>
I've also tried the following function:
def empty(self):
for each in self.cart:
del each
self.save()
Your insight would be much appreciated! Full Cart.py below:
class Cart(object):
def __init__(self, request):
self.session = request.session
if not hasattr(settings, 'CART_SESSION_KEY'):
raise KeyNotSet('Session key identifier is missing in settings')
if not hasattr(settings, 'PRODUCT_MODEL'):
raise KeyNotSet('Product model is missing in settings')
cart = self.session.get(settings.CART_SESSION_KEY)
if not cart:
is_model_set = hasattr(settings, 'USE_CART_MODELS')
if is_model_set and settings.USE_CART_MODELS:
# cart =
pass
else:
cart = self.session[settings.CART_SESSION_KEY] = {}
self.cart = cart
def add(self, product, price, quantity=1,):
product_id = str(product.id)
if product_id not in self.cart:
self.cart[product_id] = {'price': str(price), 'quantity': 0}
self.cart[product_id]['quantity'] = int(quantity)
self.save()
self.cart[product_id]['quantity'] = int(quantity)
self.save()
def save(self):
self.session[settings.CART_SESSION_KEY] = self.cart
self.session.modified = True
def remove(self, product):
product_id = str(product.id)
if product_id in self.cart:
del self.cart[product_id]
self.save()
def empty(self):
for each in self.cart:
del each
self.save()
def __iter__(self):
product_ids = self.cart.keys()
splitted = settings.PRODUCT_MODEL.split('.')
app_label = splitted[0]
model_name = splitted[1]
try:
model = apps.get_model(app_label, model_name)
except LookupError:
message = 'Model {} not found in app {}'
raise ModelDoesNotExist(message.format(model_name, app_label))
products = model.objects.filter(id__in=product_ids)
for product in products:
self.cart[str(product.id)]['product'] = product
for item in self.cart.values():
item['price'] = Decimal(item['price'])
item['total_price'] = item['price'] * item['quantity']
yield item
def __len__(self):
return sum(item['quantity'] for item in self.cart.values())
@property
def total_price(self):
return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values())
@property
def cart_length(self):
return sum(item['quantity'] for item in self.cart.values())
def clear(self):
self.session.cart[settings.CART_SESSION_KEY] = {}
self.session.modified = True
Upvotes: 0
Views: 205
Reputation: 23024
The problem is that when you create the cart you create an empty dictionary and assign it to both self.cart
and the session:
cart = self.session[settings.CART_SESSION_KEY] = {}
self.cart = cart
But when you clear the cart, you create an empty dictionary and assign it to only the session, leaving self.cart
pointing at the original - still populated - dictionary:
self.session.cart[settings.CART_SESSION_KEY] = {} # self.cart still populated
Rather than assign a new dictionary in clear()
, you could just clear the original dictionary:
def clear(self):
self.cart.clear() # Affects both self.cart and session
self.session.modified = True
Upvotes: 1