Commits

Chris Beaven  committed c8de004

Incomplete, but proof-of-concept for middleware and attaching carts directly to the request object

  • Participants
  • Parent commits c07d370

Comments (0)

Files changed (4)

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 import settings
+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