简体   繁体   中英

Add items one at a time to a “cart” using checkboxes with Django, Ajax, and Jquery

New code now included, but still not working...

I am trying to use checkboxes to select an item(s) an add it to the "cart" at the top of the page. Every item on the page has a checkbox next to it that, when selected, should add the item to the cart and display that item name in the "cart" section at the top of the page. So, as the user goes down the page and checks an item, I want that item name to appear in the "cart" section at the top of page.

(ie check an item and the item name appears at top of page; check another item and that item name appears beside the first item at the top of the page; etc.)

With previous versions of my code, I have been able to get the first item listed on the page (and only the first item) to actually show in the "cart" section. I have tried everything I can, but I am completely new to Django, Ajax, and Jquery. Can someone please help!? Thank you!

"cart" section of list.html:

    <div id="programCart">
        <table cellpadding="5" cellpadding ="2" border="2" id="selected_programs_cart">
            <tbody>
                <tr>
                <td id="selectionsHere"> SampleSelection1 </td>
                </tr>
            </tbody>
        </table>    
    </div> 

html that lists the items with a checkbox next to each, part of list.html (these items are displayed with a larger 'for' loop):

<td>
<form id="programs-selected" method="GET" action="select_citations">
    <script type="text/javascript" src="/static/js/citations.js"></script>
    <ul>
        <li><input type="checkbox" id="programCheckbox" name="programs_to_add" value="{{software.id}}" />
        </li>
    </ul>
</td>
</form>

selectitems.js:

$('#programCheckbox').click(function(){
    var softwareID
    softwareID = $(this).attr("value")

    $.get('add_to_cart', function(data){
        $tbody = $("selected_programs_cart").find('tbody');
        $.each(data, function(){
            var displayCart = json.addingToCart;
            for (var key in displayCart)
                if (key == 'cart'){
                    var value = displayCart[key];
                    for (var softwareName in value)
                        $("<td>" + softwareName + "<td>").appendTo($tbody);
            };
        });
    });
});

itemview.py

def add_to_cart(request):
#dict of 'cart' to list of selected programs to return
to_JSON = {}

#Programs are already in the cart and the "cart" key already exists in the session-
if 'cart' in request.session:
    logger.warning("cart found")
    software_id = request.GET.get('softwareID')
    softwareObject = Software.objects.get(pk='software_id')
    softwareName = softwareObject.title

    addingToCart = request.session.get('cart')
    request.session['addingToCart'].append(softwareName)

    to_JSON = request.session['addingToCart']

#first time clicking on a program, no existing cart in session: the session should store 'cart' as the key and a list of selected programs as the value
else:
    logger.warning("cart not found")
    #get the softwareID of the most recently clicked program
    software_id = request.GET.get('softwareID')
    if software_id == None:
        #oops, can't retrieve this from the request
        logger.warning("cannot find software_id in the request")
        return HttpResponse(request) # TODO: there's probably a better way to handle this
    else:
        logger.warning( "request.GET.get('softwareID'): {}".format(request.GET.get('softwareID')) )
        try:
            softwareObject = Software.objects.get(pk='software_id')
        except Software.DoesNotExist as e:
            logger.warning("oh oh, Someone is trying to access a Software ID that doesn't exist: {}".format(e))
            # TODO: what to do if this happens?
        except ValueError as e:
            logger.warning("oh dear: {}".format(e) )

            #TODO: if an exception happens, the softwareObject won't exist, what should happen then?
        softwareName = softwareObject.title

        #create an entry in the session dictionary for the cart and program list
        request.session['cart'] = []

        #add the first selected program to the list
        request.session['cart'].append(softwareName)

        addingToCart = request.session['cart']
        to_JSON = request.session['addingToCart']

response_data = json.dumps(to_JSON)
return HttpResponse(response_data, content_type='application/json')

#return HttpResponse(json.dumps(cart, ensure_ascii=False), content_type='application/json')

This question is fairly broad, and will most likely get closed or downvoted out of existence, but I thought I'd try to steer you in the right direction.

Your view function is pretty far from being able to return JSON that your jQuery method can consume and use to update the DOM. Here's some pseudo-code:

import json

from django.http import HttpResponse

# or if you're using Django 1.7, you can use the JsonResponse class:
# https://docs.djangoproject.com/en/1.7/ref/request-response/#jsonresponse-objects

from your_app.models import Software


def add_to_cart(request):
    # get an existing cart from the request
    cart = request.session.get('cart', {'items': []})

    # get the objects for the ids in the request
    software_ids = request.GET.getlist('software_ids')
    software = Software.objects.filter(id__in=software_ids)

    # append the items to the cart
    cart['items'].append(software)

    # set the cart into session so you can persist it across requests
    request.session['cart'] = cart

    # dump the cart to JSON and send back a the response
    return HttpResponse(json.dumps(cart, ensure_ascii=False),
        content_type='application/json')

Something important to keep in mind here is that anything you want to put into session has to be serializeable to a string. The jsonpickle module is great for encoding/decoding complex Python objects to JSON.

Keeping concerns separate, you might want to pass the data returned from the response to a JavaScript templating function, like Underscore 's _.template() and pass it the data from the response, rather than return HTML from the view.

There are also pre-made carts for Django: django-cart and django-carton . There's also this comparison chart of Django e-Commerce packages. Hope that gets you going.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM