0

This is driving me crazy. I am building an ecommerce app, with the cart in Django-carton. When I add an item to the cart, I can get the item's id from the context into the store, and pass it into my Ajax call and to the view when a customer adds the item with a button click.

I want the customer to be able to delete and edit quantities in the cart using a button, and am now trying to create my delete and my edit quantity functions. I'm stuck because I don't understand how to pass the id the the view in Ajax. The id isn't in the item context object. I can get the id in the view by printing ids = request.session['CART'], but it does not have the current id. The items in context are limited to the following:

self.product = product
self.quantity = int(quantity)
self.price = Decimal(str(price))

The example in Django-carton's documentation has this example, which doesn't use Javascript:

views:

def remove(request):
    cart = Cart(request.session)
    product = Product.objects.get(id=request.GET.get('id'))
    cart.remove(product)
    return HttpResponse("Removed")

urls:

u`rl(r'^remove/$', 'remove', name='shopping-cart-remove'),`

In my view, I can get the ids of all of the objects in the cart with

cart = Cart(request.session)
ids = request.session['CART']

which gives me the following object:

{u'meal_pk': 15, u'price': u'5', u'quantity': 39}

But this doesn't actually seem helpful. This is my first encounter with sessions. I've been reading through the code here https://github.com/lazybird/django-carton/blob/master/carton/cart.py How can I edit or delete an item in my cart?

fstopzero
  • 1,073
  • 2
  • 10
  • 24

1 Answers1

1

You can still call the remove view via AJAX quite easily with Javascript; unless otherwise specified, the view does not care if the request is submitted via AJAX. So, we can set that up easily w/ JQuery.

So, in a template showing the shopping cart, for example:

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

<script type="text/javascript" src="path/to/jquery.js">/script>

{% for item in cart.items %}
    <a onclick='AjaxRemove("{% url 'shopping-cart-remove' %}?id={{ item.product.id }}")'>Remove this item</a>
{% endfor %}

<script type="text/javascript">
    function AjaxRemove(remove_url) {
        $.ajax({
            url: remove_url,
            success: function(response) {alert(response);},
            error: function() {alert("Couldn't remove item");}  
        })
</script>

will remove the item and give an alert if the AJAX request responds with success.

You can further customize the view response to respond differently to AJAX requests using request.is_ajax():

def remove(request):
    cart = Cart(request.session)
    product = Product.objects.get(id=request.GET.get('id'))
    cart.remove(product)
    if request.is_ajax():
        # do something, respond differently
        return HttpResponse("Removed (via AJAX)")
    return HttpResponseRedirect(reverse('shopping-cart-show'))
Ian Price
  • 7,416
  • 2
  • 23
  • 34
  • Forgive the possibly stupid question - with sessions I can edit in JS, and not use my views at all? I'm so confused about how this works. – fstopzero Jun 14 '16 at 18:47
  • Sessions are accessible via the backend only, so you must create a view/endpoint to update or retrieve sessions variables. What is happening above: When clicking on the remove button for an item, use JQuery to make an Ajax call to the Django view `remove`. Django reacts in turn executing the view, remove the item from the session. From there, you could include code to remove the item from page the client is viewing through JS. If you removed an item from the cart and then called the shopping cart view again, the item wouldn't appear. – Ian Price Jun 14 '16 at 18:51