Skip to content

Instantly share code, notes, and snippets.

@rudyryk
Last active August 29, 2015 14:01
Show Gist options
  • Save rudyryk/4390eaac85cfe6707659 to your computer and use it in GitHub Desktop.
Save rudyryk/4390eaac85cfe6707659 to your computer and use it in GitHub Desktop.
Simple and agnostic session based cart for Django
# -*- coding: utf-8 -*-
#
# No Rights Reserved
# http://creativecommons.org/publicdomain/zero/1.0/
"""Agnostic minimal session based cart for Django.
Just copy-n-paste this snippet to your project.
See `Cart` class reference below for details.
"""
import decimal
def column(name):
return lambda x: x[name]
class Cart(object):
"""Agnostic minimal session based cart for Django.
Basic usage example - in views::
from my_app.models import Product, Order
def shop_view(request):
# How to get cart object
cart = Cart.get_cart(request)
products = Product.objects.all()
return render(request, 'my_shop.html', {'cart': cart, 'products': products})
def add_product_view(request):
cart = Cart.get_cart(request)
if request.method == 'POST':
pk = request.POST['pk']
quantity = request.POST['quantity']
product = get_object_or_404(Product, pk=pk)
# How to add item to cart
cart.add_item(key=product.pk, quantity=quantity,
price=product.price, info={'title': product.title})
def create_order(request):
# How to get items in cart and create order
cart = Cart.get_cart(request)
products = Product.objects.filter(id__in=cart.get_keys())
for product in products:
cart_item = cart.get_item(product.pk)
# Here's our knowledge edge, you should manually add product
# to your custom Order model ...
Usage example - in templates::
{% for item in cart.get_items %}
<p>
{{ item.info.title }}: {{ item.quantity }} x {{ item.price }} = {{ item.total }}
</p>
{% empty %}
Cart is empty.
{% endfor %}
"""
session_key = 'cart'
def __init__(self, **data):
self._data = data
@classmethod
def get_cart(cls, request):
data = request.session.setdefault(cls.session_key, {})
return cls(**data)
@classmethod
def delete_cart(cls, request):
if cls.session_key in request.session:
del request.session[cls.session_key]
def save(self, request):
request.session[self.session_key] = self._data
def delete(self, request):
self.delete_cart(request)
def clear(self):
if 'items' in self._data:
del self._data['items']
def add_item(self, key=None, quantity=None, price=None, info=None):
keys, items = self.get_keys(), self.get_items()
price = decimal.Decimal(price or '0.00')
quantity = 1 if quantity is None else int(quantity)
if key in keys:
item = items[keys.index(key)]
else:
item = {
'key': key,
'quantity': 0,
'price': price,
'total': 0,
'info': info or {}
}
items.append(item)
item['quantity'] = item['quantity'] + quantity
item['total'] = item['quantity'] * item['price']
def del_item(self, key):
keys, items = self.get_keys(), self.get_items()
if key in keys:
del items[keys.index(key)]
def get_item(self, key):
keys, items = self.get_keys(), self.get_items()
if key in keys:
return items[keys.index(key)]
def get_items(self):
return self._data.setdefault('items', [])
def get_keys(self):
return map(column('key'), self.get_items())
def get_total(self):
return sum(map(column('total'), self.get_items()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment