Last active
August 29, 2015 14:01
-
-
Save rudyryk/4390eaac85cfe6707659 to your computer and use it in GitHub Desktop.
Simple and agnostic session based cart for Django
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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