Skip to content

Commit

Permalink
Fist commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Sylvain committed Nov 29, 2012
0 parents commit 315976e
Show file tree
Hide file tree
Showing 22 changed files with 719 additions and 0 deletions.
Empty file added CHANGES
Empty file.
42 changes: 42 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Copyright (C) 2012, lazybird

Permission is hereby granted, free
of charge, to any person obtaining a
copy of this Software to use it
without limitation, including copy,
modify, merge, publish, pulverize,
distribute, synergize, compost,
defenestrate, sublicense, sell
copies of the Software and permit
persons to whom the Software is
furnished to do so - subject to the
following conditions:

The above copyright notice and this
permission notice shall be included
in all copies or substantial
portions of the Software.

If the Author of the Software needs
a place to crash and you have a sofa
available, you should maybe give the
Author a break and let him sleep on
your couch.

If you are caught in a dire
situation wherein you only have
enough time to save one person out
of a group, and the Author is a
member of that group, you must save
the Author.

THE SOFTWARE IS PROVIDED "AS IS",
WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO BLAH BLAH BLAH ISN'T
IT FUNNY HOW UPPER-CASE MAKES IT
SOUND LIKE THE LICENSE IS ANGRY AND
SHOUTING AT YOU.

Do what makes you happy,
Just don't sue me.
5 changes: 5 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include *.md
include LICENSE
include RELEASES
include CHANGES
recursive-include example *
250 changes: 250 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@

Django Carton
=============


:::text
+------+
/| /|
+-+----+ | django-carton is a simple and lightweight container
| | | | for shopping carts and wish lists.
| +----+-+
|/ |/
+------+



* Simple: You decide how to implement the views, templates and payment
processing.
* Lightweight: The cart lives in the session.
* A container: You define your product model the way you want.


Usage Example
-------------

View:

from django.http import HttpResponse

from carton.cart import Cart
from products.models import Product

def add(request):
cart = Cart(request.session)
product = Product.objects.get(id=request.GET.get('product_id'))
cart.add(product, price=product.price)
return HttpResponse("Added")

def show(request):
return render(request, 'shopping/show-cart.html')


We are assuming here that your products are defined in an application
called ``products``.

Template:

{% load carton_tags %}
{% get_cart as cart %}

{% for item in cart.items %}
{{ item.product.name }}
{{ item.quantity }}
{{ item.total_price }}
{% endfor %}


This project is shipped with an application example called ``shopping``
implementing basic add, remove, display features.
To use it, you will need to install the ``shopping`` application and
include the URLs in your project ``urls.py``

# settings.py
INSTALLED_APPS = (
'carton',
'shopping',
'products',
)

# urls.py
urlpatterns = patterns('',
url(r'^shopping-cart/', include('shopping.urls')),
)


Assuming you have some products defined, you should be able to
add, show and remove products like this:

/shopping-cart/add/?id=1
/shopping-cart/show/
/shopping-cart/remove/?id=1


Installation
------------

Just install the package using something like pip and add ``carton`` to
your ``INSTALLED_APPS`` setting.


Abstract
--------

The cart is an object that's stored in session. Products are associated
to cart items.

Cart
|-- CartItem
|----- product
|----- price
|----- quantity

A cart item stores a price, a quantity and an arbitrary instance of
a product model.


You can access all your product's attributes, for instance it's name:

{% for item in cart.items %}
{{ item.price }}
{{ item.quantity }}
{{ item.product.name }}
{% endfor %}



Managing Cart Items
-------------------

These are simple operations to add, remove and access cart items:

>>> apple = Product.objects.all()[0]
>>> cart.add(apple, price=1.5)
>>> apple in cart
True
>>> cart.remove(apple)
>>> apple in cart
False

>>> orange = Product.objects.all()[1]
>>> cart.add(apple, price=1.5)
>>> cart.total
Decimal('1.5')
>>> cart.add(orange, price=2.0)
>>> cart.total
Decimal('3.5')


Note how we check weather the product is in the cart - The following
statements are different ways to do the same thing:

>>> apple in cart
>>> apple in cart.products
>>> apple in [item.product for item in cart.items]


The "product" refers to the database object. The "cart item" is where
we store a copy of the product, it's quantity and it's price.

>>> cart.items
[CartItem Object (apple), CartItem Object (orange)]

>>> cart.products
[<Product: apple>, <Product: orange>]


Clear all items:

>>> cart.clear()
>>> cart.total
0


Increase the quantity by adding more products:

>>> cart.add(apple, price=1.5)
>>> cart.add(apple) # no need to repeat the price.
>>> cart.total
Decimal('3.0')

Note that the price is only needed when you add a product for the first time.

>>> cart.add(orange)
*** ValueError: Missing price when adding a cart item.


You can add several products at the same time:

>>> cart.clear()
>>> cart.add(orange, price=2.0, quantity=3)
>>> cart.total
Decimal('6')
>>> cart.add(orange, quantity=2)
>>> cart.total
Decimal('10')


The price is relevant only the first time you add a product:

>>> cart.clear()
>>> cart.add(orange, price=2.0)
>>> cart.total
Decimal('2')
>>> cart.add(orange, price=100) # this price is ignored
>>> cart.total
Decimal('4')


Note how the price is ignored on the second call.


You can change the quantity of product that are already in the cart:

>>> cart.add(orange, price=2.0)
>>> cart.total
Decimal('2')
>>> cart.set_quantity(orange, quantity=3)
>>> cart.total
Decimal('6')
>>> cart.set_quantity(orange, quantity=1)
>>> cart.total
Decimal('2')
>>> cart.set_quantity(orange, quantity=0)
>>> cart.total
0
>>> cart.set_quantity(orange, quantity=-1)
*** ValueError: Quantity must be positive when updating cart



Removing all occurrence of a product:

>>> cart.add(apple, price=1.5, quantity=4)
>>> cart.total
Decimal('6.0')
>>> cart.remove(apple)
>>> cart.total
0
>>> apple in cart
False


Remove a single occurrence of a product:

>>> cart.add(apple, price=1.5, quantity=4)
>>> cart.remove_single(apple)
>>> apple in cart
True
>>> cart.total
Decimal('4.5')
>>> cart.remove_single(apple)
>>> cart.total
Decimal('3.0')
>>> cart.remove_single(apple)
>>> cart.total
Decimal('1.5')
>>> cart.remove_single(apple)
>>> cart.total
0

3 changes: 3 additions & 0 deletions carton/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""django-carton is a simple and lightweight container for shopping carts and wish lists."""

__version__ = '0.1.0'
Loading

0 comments on commit 315976e

Please sign in to comment.