Quickstart

This document demonstrates how you can use Easycart to implement the shopping cart functionality in your django project.

Install the app

Before you do anything else, ensure that Django Session Framework is enabled and configured.

Use pip to install Easycart:

$ pip install django-easycart

Add the app to your INSTALLED_APPS setting:

INSTALLED_APPS = [
    ...
    'easycart',
]

Define your cart class

First, create a new django application:

$ python manage.py startapp cart

It will contain things not provided by Easycart, such as templates and static files. Those are unique to each project, so it’s your responsibility to provide them.

Next, we need to create a customized cart class. Don’t worry, it’s really easy, just subclass BaseCart and override its get_queryset() method:

# cart/views.py
from easycart import BaseCart

# We assume here that you've already defined your item model
# in a separate app named "catalog".
from catalog.models import Item


class Cart(BaseCart):

    def get_queryset(self, pks):
        return Item.objects.filter(pk__in=pks)

Now, our class knows how to communicate with the item model.

Note

For simplicity’s sake, the example above supposes that a single model is used to access all database information about items. If you use multi-table inheritance, see this link.

There are many more customizations you can make to the cart class, check out Cookbook and Reference, after you complete this tutorial.

Plug in ready-to-use views

Every cart needs to perform tasks like adding/removing items, changing the quantity associated with an item or emptying the whole cart at once. You can write your own views for that purpose, using the cart class we’ve created above, but what’s the point in reinventing the wheel? Just use the ones shipped with Easycart.

Add the following to your project settings:

EASYCART_CART_CLASS = 'cart.views.Cart'

Create cart/urls.py:

from django.conf.urls import url

urlpatterns = [
    # This pattern must always be the last
    url('', include('easycart.urls'))
]

Include it in the root URLconf:

url(r'^cart/', include('cart.urls')),

Now, the cart can be operated by sending POST-requests to Easycart urls:

URL name View
cart-add AddItem
cart-remove RemoveItem
cart-change-quantity ChangeItemQuantity
cart-empty EmptyCart

Tip

It would be wise to create a javascript API to handle these requests. Here’s an oversimplified example of such an API that can serve as a starting point. It uses a bit of jQuery and assumes that CSRF-protection has already been taken care of.

var cart = {
    add: function (pk, quantity) {
      quantity = quantity || 1
      return $.post(URLS.addItem, {pk: pk, quantity: quantity}, 'json')
    }

    remove: function (itemPK) {
      return $.post(URLS.removeItem, {pk: itemPK}, 'json')
    }

    changeQuantity: function (pk, quantity) {
      return $.post(URLS.changeQuantity, {pk: pk, quantity: quantity}, 'json')
    }

    empty: function () {
      $.post(URLS.emptyCart, 'json')
    }
}

Inline a script similar to the one below in your base template, so you don’t have to hardcode the urls.

<script>
var URLS = {
  addItem:        '{% url "cart-add" %}',
  removeItem:     '{% url "cart-remove" %}',
  changeQuantity: '{% url "cart-change-quantity" %}',
  emptyCart:      '{% url "cart-empty" %}',
}
</script>

Access the cart from templates

To enable the built-in cart context processor, add context_processors.cart to your project settings:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                # other context processors
                'easycart.context_processors.cart',
            ],
        },
    },
]

Now, the cart can be accessed in any template through context variable cart like this:

{{ cart.item_count }}
{{ cart.total_price }}

{% for item in cart.list_items %}
<div>
    {# Access the item's model instance using its "obj" attribute #}
    {{ item.obj.name }}
    <img src="{{ item.obj.picture.url }}">
    {{ item.price }}
    {{ item.quantity }}
    {{ item.total }}
</div>
{% endfor %}

The name of the variable can be changed using the EASYCART_CART_VAR setting.


Well, that’s all. Of course, you still need to write some front-end scripts and create additional views (for instance, for order processing), but all of this is far beyond the scope of this document.