juju
juju

Reputation: 994

Django trouble creating function to delete all items in sessions / cart

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

Answers (1)

Will Keeling
Will Keeling

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

Related Questions