Permalink
Browse files

Demo shop: wishlist reimplementation

  • Loading branch information...
1 parent 94471e1 commit df93bfc20aefdf6c94ea5d4330036329fe4b186c @paluh paluh committed Jan 24, 2012
View
@@ -1,30 +1,40 @@
from django.conf.urls.defaults import patterns, url
-from django.shortcuts import get_object_or_404, redirect
+from django.core.exceptions import ObjectDoesNotExist
+from django.http import Http404
import satchless.cart.app
-import satchless.cart.signals
from categories.app import product_app
-cart_app = satchless.cart.app.MagicCartApp(product_app)
+from . import handler
+from . import models
+
+class CartApp(satchless.cart.app.MagicCartApp):
+ AddToCartHandler = handler.AddToCartHandler
+
+cart_app = CartApp(product_app)
+
class WishlistApp(satchless.cart.app.MagicCartApp):
app_name = 'wishlist'
namespace = 'wishlist'
cart_type = 'wishlist'
- Cart = cart_app.Cart
- CartItem = cart_app.CartItem
+ Cart = models.Wishlist
+ CartItem = models.WishlistItem
+ AddToCartHandler = handler.AddToWishlistHandler
+
+ def __init__(self, cart_app, *args, **kwargs):
+ self.cart_app = cart_app
+ super(WishlistApp, self).__init__(*args, **kwargs)
def add_to_cart(self, request, wishlist_item_id):
- wishlist = self.Cart.objects.get_or_create_from_request(request,
- self.cart_type)
- item = get_object_or_404(wishlist.items.all(), id=wishlist_item_id)
- cart = self.Cart.objects.get_or_create_from_request(request, 'cart')
- form_result = cart.add_item(variant=item.variant, quantity=1)
- satchless.cart.signals.cart_item_added.send(sender=type(form_result.cart_item),
- instance=form_result.cart_item,
- result=form_result,
- request=request)
- return redirect('cart:details')
+ wishlist = self.get_cart_for_request(request)
+ try:
+ item = wishlist.get_item(id=wishlist_item_id)
+ except ObjectDoesNotExist:
+ raise Http404()
+ cart = self.cart_app.get_cart_for_request(request)
+ cart.add_item(variant=item.variant, quantity=1)
+ return self.cart_app.redirect('details')
def get_urls(self):
parent_urls = super(WishlistApp, self).get_urls()
@@ -33,5 +43,4 @@ def get_urls(self):
name='add-to-cart'),
)
-
-wishlist_app = WishlistApp(product_app)
+wishlist_app = WishlistApp(cart_app=cart_app, product_app=product_app)
@@ -10,7 +10,7 @@ def carts_sizes(request):
cart_size = 0
try:
wishlist_size = (wishlist_app.get_cart_for_request(request)
- .items.aggregate(cart_size=models.Sum('quantity')))['cart_size'] or 0
+ .items.count()) or 0
except wishlist_app.Cart.DoesNotExist:
wishlist_size = 0
return {'cart_size': cart_size,
@@ -1,16 +1,18 @@
# -*- coding:utf-8 -*-
from django import forms
-class AddToCartForm(forms.Form):
- quantity = forms.DecimalField(initial=1)
-
+class AddToCartBaseForm(forms.Form):
def __init__(self, data=None, *args, **kwargs):
typ = kwargs.pop('typ')
# validate only when correct button was pressed
if data and not typ in data:
data = None
self.cart = kwargs.pop('cart', None)
- super(AddToCartForm, self).__init__(data=data, *args, **kwargs)
+ super(AddToCartBaseForm, self).__init__(data=data, *args, **kwargs)
+
+
+class AddToCartForm(AddToCartBaseForm):
+ quantity = forms.DecimalField(initial=1)
def clean(self):
data = super(AddToCartForm, self).clean()
@@ -24,7 +26,8 @@ def clean(self):
def save(self):
return self.cart.add_item(self.get_variant(), self.cleaned_data['quantity'])
-class AddToWishlistForm(AddToCartForm):
+
+class AddToWishlistForm(AddToCartBaseForm):
def save(self):
return self.cart.add_item(self.get_variant(), 1)
@@ -1,18 +1,26 @@
-from models import DemoCart
-from satchless.cart.handler import AddToCartHandler
+import satchless.cart.handler
from . import forms
-add_to_cart_handler = AddToCartHandler('cart',
- addtocart_formclass=forms.AddToCartForm,
- cart_class=DemoCart)
+class AddToCartHandler(satchless.cart.handler.AddToCartHandler):
+ def __init__(self, **kwargs):
+ kwargs['addtocart_formclass'] = kwargs.get('addtocart_formclass',
+ forms.AddToCartForm)
+ super(AddToCartHandler, self).__init__(**kwargs)
-add_to_wishlist_handler = AddToCartHandler('wishlist',
- details_view='wishlist:details',
- addtocart_formclass=forms.AddToWishlistForm,
- cart_class=DemoCart)
+ def __call__(self, instances=None, request=None, extra_context=None, **kwargs):
+ if request and (request.method == 'GET' or (request.method == 'POST' and
+ self.cart_app.app_name in request.POST)):
+ return super(AddToCartHandler, self).__call__(instances=instances, request=request,
+ extra_context=extra_context, **kwargs)
+ return extra_context
+
+
+class AddToWishlistHandler(AddToCartHandler):
+ def __init__(self, **kwargs):
+ kwargs['addtocart_formclass'] = kwargs.get('addtocart_formclass',
+ forms.AddToWishlistForm)
+ kwargs['form_attribute'] = kwargs.get('form_attribute',
+ 'wishlist_form')
+ super(AddToWishlistHandler, self).__init__(**kwargs)
-def carts_handler(instances=None, request=None, extra_context=None, **kwargs):
- if request.method == 'POST' and 'wishlist' in request.POST:
- return add_to_wishlist_handler(instances, request, extra_context, **kwargs)
- return add_to_cart_handler(instances, request, extra_context, **kwargs)
@@ -3,14 +3,15 @@
from satchless.cart import signals
-def add_to_cart_listener(sender, instance, request, **kwargs):
+def add_to_cart_listener(sender, instance, request, result, **kwargs):
real_variant = instance.variant.get_subtype_instance()
- if instance.cart.typ == 'satchless_cart':
- messages.success(request, ugettext('<strong>Great success!</strong> %s was '
- 'added to your cart.') % real_variant)
- else:
- messages.success(request, ugettext('<strong>Bookmarked!</strong> %s was added '
- 'to your wishlist.') % real_variant)
+ if result.quantity_delta > 0:
+ if instance.cart.typ == 'satchless_cart':
+ messages.success(request, ugettext(u'<strong>Great success!</strong> %s was '
+ 'added to your cart.') % real_variant)
+ else:
+ messages.success(request, ugettext(u'<strong>Bookmarked!</strong> %s was added '
+ 'to your wishlist.') % real_variant)
def start_listening():
signals.cart_item_added.connect(add_to_cart_listener)
@@ -0,0 +1,42 @@
+from django.db import models
+import satchless.cart.models
+
+import products.models
+
+class Wishlist(satchless.cart.models.Cart):
+
+ def add_item(self, variant, quantity):
+ return self.replace_item(variant, 1)
+
+ def replace_item(self, variant, quantity, **kwargs):
+ if quantity > 0:
+ wishlist_item, created = self.items.get_or_create(variant=variant)
+ quantity = 1
+ if created:
+ quantity_delta = 1
+ else:
+ quantity_delta = 0
+ else:
+ try:
+ wishlist_item = self.items.get(variant=variant)
+ wishlist_item.delete()
+ quantity = 0
+ quantity_delta = -1
+ except WishlistItem.DoesNotExist:
+ wishlist_item = None
+ quantity = 0
+ quantity_delta = 0
+ return satchless.cart.models.QuantityResult(wishlist_item, quantity, quantity_delta)
+
+ def is_empty(self):
+ return not self.items.exists()
+
+
+class WishlistItem(models.Model):
+
+ cart = models.ForeignKey(Wishlist, editable=False, related_name='items')
+ variant = models.ForeignKey(products.models.Variant,
+ editable=False, related_name='+')
+
+ class Meta:
+ unique_together = ('cart', 'variant')
@@ -0,0 +1,51 @@
+import satchless.util.tests
+
+from categories.app import product_app
+from .app import wishlist_app
+import products.models
+
+
+class ViewsTestCase(satchless.util.tests.ViewsTestCase):
+ def setUp(self):
+ self.category = product_app.Category.objects.create(name='posh',
+ slug='posh')
+ self.product = products.models.Hat.objects.create(name='top hat',
+ slug='top-hat',
+ price=10)
+ self.product.categories.add(self.category)
+
+ def _get_or_create_cart_for_client(self, cart_app, client=None):
+ client = client or self.client
+ self._test_status(cart_app.reverse('details'),
+ client_instance=client)
+ token = client.session[cart_app.cart_session_key]
+ return cart_app.Cart.objects.get(token=token)
+
+ def test_add_to_wishlist(self):
+ wishlist = self._get_or_create_cart_for_client(wishlist_app,
+ client=self.client)
+ # wishlist var indicates which handler should serve this request
+ data = {
+ 'wishlist': 'wishlist',
+ }
+ self._test_POST_status(self.product.get_absolute_url(),
+ data=data, status_code=302,
+ client_instance=self.client)
+ self.assertEqual([i.variant.get_subtype_instance().product for i in wishlist.get_all_items()],
+ [self.product])
+
+ def test_add_to_cart_from_wishlist(self):
+ wishlist = self._get_or_create_cart_for_client(wishlist_app)
+ # add item to wishlist
+ wishlist_item = wishlist.add_item(self.product.variants.get(), 1).cart_item
+ # move item from wishlist into cart
+ add_to_cart_url = wishlist_app.reverse('add-to-cart', args=(wishlist_item.pk,))
+ self._test_POST_status(add_to_cart_url, status_code=302,
+ client_instance=self.client)
+
+ # check cart content
+ cart = self._get_or_create_cart_for_client(wishlist_app.cart_app)
+ cart_items = cart.get_all_items()
+ self.assertEqual(len(cart_items), 1)
+ self.assertEqual(cart_items[0].variant.get_subtype_instance(),
+ wishlist_item.variant.get_subtype_instance())
@@ -3,9 +3,9 @@
from . import models
import products.models
-class CategoryApp(satchless.category.app.CategorizedProductApp):
+class CategorizedProductApp(satchless.category.app.CategorizedProductApp):
Category = models.Category
Product = products.models.Product
Variant = products.models.Variant
-product_app = CategoryApp()
+product_app = CategorizedProductApp()
@@ -196,7 +196,7 @@
},
'cart-product': {
'size': ('156', '156'),
- 'crop': False,
+ 'crop': True,
},
'order-preview': {
'size': ('56', '56'),
@@ -81,7 +81,7 @@
</p>
</div>
<input class="button cart" name="cart" type="submit" value="{% trans "Add to cart" %}" />
- <input class="wishlist" name="wishlist" type="submit" value="{% trans "Add to whishlist" %}" />
+ <input class="wishlist" name="wishlist" type="submit" value="{% trans "Add to wishlist" %}" />
{% endif %}
</div>
</div>
View
@@ -90,7 +90,7 @@ def get_urls(self):
class MagicCartApp(CartApp):
CartItem = None
- product_app = None
+ AddToCartHandler = handler.AddToCartHandler
def __init__(self, product_app, **kwargs):
self.product_app = product_app
@@ -101,8 +101,7 @@ def __init__(self, product_app, **kwargs):
self.CartItemForm = (
self.CartItemForm or
self.construct_cart_item_form_class(self.CartItem))
- add_to_cart_handler = handler.AddToCartHandler(cart_app=self,
- addtocart_formclass=forms.AddToCartForm)
+ add_to_cart_handler = self.AddToCartHandler(cart_app=self)
product_app.register_product_view_handler(add_to_cart_handler)
super(MagicCartApp, self).__init__(**kwargs)

0 comments on commit df93bfc

Please sign in to comment.