Commits

Anonymous committed 9015049 Merge

Merged contributions from SmileyChris

  • Participants
  • Parent commits 5747241, c8de004

Comments (0)

Files changed (6)

File session_cart/cart.py

 '''Session based shopping cart'''
 
+
 class CartItem(object):
     '''Lightweight container for cart items'''
     __slots__ = ('item', 'quantity',)
         self.quantity = quantity and quantity or 0
 
     def __repr__(self):
-        return 'CartItem(%r, %r)' % (self.item, self.quantity,)
+        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 __repr__( self ):
         return ','.join([repr(x) for x in self])
-

File session_cart/context_processor.py

-
-from session_cart import cart
-
-def cart(request):
-    return { 'cart': cart.Cart(request.session) }
-

File session_cart/context_processors.py

+from session_cart.utils import get_carts
+
+
+def carts(request):
+    """
+    Returns all session carts as 'carts', and the default cart (if one is
+    provided) as 'cart'.
+
+    """
+    context = {}
+    carts = getattr(request, 'carts', None)
+    if carts:
+        if 'default' in get_carts():
+            context['cart'] = carts.default
+        context['carts'] = carts
+    return context

File session_cart/middleware.py

+from session_cart.utils import get_carts
+
+
+class CartMiddleware(object):
+    """
+    Middleware that handles adding session carts to the request object.
+
+    """
+
+    def process_request(self, request):
+        """
+        Add the carts to the request object. 
+        """
+        request.carts = object()
+        for name, Cart in get_carts().items():
+            setattr(request.carts, name, Cart(request))
+        
+        if 'default' in get_carts():
+            request.cart = property(lambda self: self.carts.default)
+
+    def process_response(self, request, response):
+        """
+        Update the session carts if they have changed.
+
+        """
+        # Don't assume the request object has carts, another layer may have
+        # returned request this middleware's process_request was called.
+        if hasattr(request, 'carts'):
+            for name in get_carts():
+                getattr(request.carts, name).save()
+        return response

File session_cart/settings.py

+from django.conf import settings
+
+CARTS = getattr(settings, 'SESSION_CARTS', {'default':
+                                            'session_cart.cart.Cart'})

File session_cart/utils.py

+from session_cart import settings
+from django.utils.importlib import import_module
+from django.core.exceptions import ImproperlyConfigured
+
+_carts = {}
+
+
+def import_cart(import_path):
+    """
+    Imports the cart class described by import_path, where import_path is the
+    full Python path to the class.
+
+    """
+    try:
+        dot = import_path.rindex('.')
+    except ValueError:
+        raise ImproperlyConfigured("%s isn't a Python path." % import_path)
+    module, classname = import_path[:dot], import_path[dot + 1:]
+    try:
+        mod = import_module(module)
+    except ImportError, e:
+        raise ImproperlyConfigured('Error importing module %s: "%s"' %
+                                   (module, e))
+    try:
+        return getattr(mod, classname)
+    except AttributeError:
+        raise ImproperlyConfigured('Module "%s" does not define a "%s" '
+                                   'class.' % (module, classname))
+
+
+def get_carts():
+    """
+    Return a dictionary of carts, where each key is the request attribute name
+    and each value is a Cart object.
+
+    """
+    if not _carts:
+        for key, value in settings.CARTS.items():
+            _carts[key] = import_cart(value)
+    return _carts