session-cart / session_cart / cart.py

'''Session based shopping cart'''
from django.core.exceptions import ImproperlyConfigured
from .utils import import_cart

class CartItem(object):
    '''Lightweight container for cart items'''
    __slots__ = ('item', 'quantity',)
    def __init__(self, item, quantity=0):
        self.item = item
        self.quantity = quantity

    def __repr__(self):
        return 'CartItem(%r, %r)' % (self.item, self.quantity)

    def __cmp__(self, other):
        if isinstance(other, CartItem):
            return cmp(self.item, other.item)
        return cmp(self.item, other)


class Cart(list):
    '''Handles a list of items stored in the session'''
    model = None
    def __init__(self, request, name='cart'):
        super(Cart, self).__init__()
        self.request = request
        self.name = name
        if self.model is None:
            from django.db import models
            from django.conf import settings
            try:
                Cart.model = import_cart(settings.CART_MODEL)
            except AttributeError:
                raise ImproperlyConfigured("%s isn't a valid Cart model." % settings.CART_MODEL)
        # Cart is stored as a list of ( item_id, quantity )
        for item, quantity in request.session.get(self.name, []):
            try:
                self.append(item, quantity)
            except self.model.DoesNotExist:
                pass

    def save(self):
        '''Save this cart to the session'''
        self.request.session[self.name] = tuple(
            (i.item.pk, i.quantity,)
            for i in self
        )

    def _get(self, item):
        '''Ensure item is an instance of self.model'''
        if not isinstance(item, self.model):
            return self.model._default_manager.get(pk=item)
        return item

    def append(self, item, quantity =1):
        item = self._get(item)
        try:
            self[self.index(item)].quantity += quantity
        except ValueError:
            super(Cart, self).append(CartItem(item, quantity))

    def index(self, value, **kwargs):
        '''Prevent duplication of (item, quantity) pairs.'''
        if isinstance(value, self.model):
            value = CartItem(value)
        return super(Cart, self).index(value)

    def remove(self, item):
        super(Cart, self).remove(self._get(item))

    def empty(self):
        '''Remove all items from cart'''
        while len(self):
            self.pop()

    def __repr__( self ):
        return ','.join([repr(x) for x in self])
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.