gnocchi-catalogue / catalogue / views.py

'''Catalogue views'''
from django.views.generic.list_detail import object_list, object_detail
from django.views.generic.simple import direct_to_template
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.db.models import Q
from django.conf import settings

from gnocchi_catalogue import models

PAGE_SIZE = int(getattr(settings, 'CATALOGUE_PAGE_SIZE', 15))

##
## Product Views
##


def product_detail(request, object_id):
    '''Render details of the current product'''
    return object_detail(request, object_id=object_id,
        template_object_name='product',
        queryset=models.Product.objects.all(),
    )

def product_list(request, tags =None):
    '''Show a list of products'''
    qset = models.Product.objects.all()
    # Filter ...
    if tags is None:
        tags = request.GET.getlist('tags')
    elif isinstance(tags, basestring):
        tags = tags.split('/')
    if tags:
        qset = qset.filter(tags__in=tags)

    if 'search' in request.REQUEST:
        search = request.REQUEST['search']
        qset = qset.filter(Q(description__icontains=search) | \
            Q(short_description__icontains=search)
        )

    options = dict(
        template_object_name='product',
        queryset=qset,
        allow_empty=True,
        extra_context={
            'tag_usage': models.Product.tags.most_common(),
        }
    )

    try:
        page_size = int(request.GET['paginate'])
    except (KeyError, ValueError):
        page_size = PAGE_SIZE
    if page_size:
        options['paginate_by'] = page_size

    return object_list(request, **options)

##
## Cart views
##

def cart_or_next(view):
    '''Decorator to redirect response to 'next' or the cart'''
    def inner(request, *a, **kw):
        '''Inner wrapper for cart_or_next'''
        view(request, *a, **kw)
        if 'next' in request.REQUEST:
            url = request.REQUEST['next']
        else:
            url = reverse('cart_details')
        return HttpResponseRedirect(url)
    return inner

@cart_or_next
def cart_add(request):
    '''Add an item to the cart'''
    product_id = request.REQUEST['product_id']
    product = models.ProductVariant.objects.get(id=product_id)
    quantity = int(request.REQUEST.get('quantity', 1))
    request.cart.add_item(product, quantity)

def cart_details(request):
    '''View the current cart'''
    return direct_to_template(request, 'catalogue/cart_list.html')

@cart_or_next
def cart_update(request):
    '''Update quantities in cart'''
    # List of item pkeys to remove
    remove_list = set(int(x) for x in request.POST.getlist('remove'))
    remove = set()
    for item in request.cart:
        if item.item.pk in remove:
            remove.add(item)
        else:
            val = int(request.POST['item_%d' % item.item.pk])
            if val:
                item.quantity = val
            else:
                remove.add(item)
    # Remove items
    for item in remove:
        request.cart.remove(item)

@cart_or_next
def cart_remove(request):
    '''Remove an item from the cart'''
    item = request.cart._get(request.REQUEST['product_id'])
    try:
        request.cart.remove(item)
    except ValueError:
        pass

@cart_or_next
def cart_empty(request):
    '''Empty the cart'''
    request.cart.empty()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.