lazybird / django-carton

A simple and lightweight application for shopping carts and wish lists.
Other
274 stars 101 forks source link

cleared cart item while logout(request) #18

Closed armsmani closed 8 years ago

armsmani commented 10 years ago

i have added item in basket after that i have logout using "logout(request)" then cart will clear all item. Because logout(request) will clear all session. How can i overcome this situation.

nelsonvarela commented 9 years ago

This question made me google how others handle this situation... can anyone exlpain.

lazybird commented 9 years ago

Hi and thanks for the comments guys, Right now, Django Carton does not bring persistent storage of your cart items. The cart is stored in the session. When the session ends, for instance when the user logs out, the cart items are lost.

There are several business logic decisions involved when you want to implement this sort of persistence throughout sessions. I can think of these points:

Here is a implementation proposal:

  1. A serialized version of the cart is stored in the database for each user - using JSONField.
  2. On every post request, add/remove/update the user's cart is updated in database.
  3. On user log-in, we retrieve the stored user's cart and rebuild a cart in session.

I use a 'cart' application within the project to wraps django-carton and provide views, models, signals to support this persistence feature.

Models - myproject.cart.models

class UserCart(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name=_('user'))
    modification_date = models.DateTimeField(_('modification date'), auto_now=True)
    items = JSONField()

Views - myproject.cart.views

class CartMixin(object):

    def process_cart(self, cart):
        return {}

    def post(self, request, *args, **kwargs):
        cart = Cart(request.session)
        response = self.process_cart(cart)
        response['count'] = cart.count
        response['unique_count'] = cart.unique_count
        if self.request.user.is_authenticated():
            (user_cart, _) = UserCart.objects.get_or_create(user=self.request.user)
            user_cart.items = cart.items_serializable
            user_cart.save()
        return JSONResponse(response)

class AddView(CartMixin, SingleObjectMixin, View):

    def process_cart(self, cart):
        added = False
        product = self.get_object()
        added = cart.add(product, price=product.price)
        return {'added': added}

class RemoveView(CartMixin, SingleObjectMixin, View):

    def process_cart(self, cart):
        removed = False
        product = self.get_object()
        if product in cart:
            removed = cart.remove(product)
        return {'removed': removed}

A rebuild function - myproject.cart.rebuild


# This is a very simple algorithm that should be customized to match your needs.

def rebuild_cart(sender, request, user, **kwargs):
    cutoff_date = implement_the_logic_for_how_long_to_keep_the_cart_items()
    try:
        user_cart = UserCart.objects.get(user=user, modification_date__gt=cutoff_date)
    except UserCart.DoesNotExist:
        user_cart = None
    if not user_cart:
        return None
    cart = Cart(request.session)
    if not cart.is_empty:
        user_cart.items = cart.items_serializable
        user_cart.save()
        return None
    cart_items = dict(user_cart.items)  # JSON object are stored as array.
    for item in cart_items.values():
        product = implement_a_way_to_get_your_product(pk=item['product_pk'])
        if product:
            cart.add(product, price=item['price'], quantity=item['quantity'])
lazybird commented 8 years ago

I'm closing this issue. Let's reopen if this is still a discussion point.

umar13893 commented 6 years ago

I also have the same issue I added this code in my logout view function It will delete all sessions except this cart session.

def user_logout(request):
    try:
        for key in list(request.session.keys()):
            if key == 'CART':
                continue
            del request.session[key]
    except KeyError:
        pass
    return HttpResponseRedirect(reversed('your_app:login'))

request.session.keys() displays all session keys Its works fine in Python3 and Django 1.11