Adding Items To Shopping Cart Django Python

Question:

EDIT
When I click add to cart this is the output to the terminal

[22/Mar/2016 07:07:44] "GET /store/add/7 HTTP/1.1" 302 0
[22/Mar/2016 07:07:44] "GET /store/ HTTP/1.1" 200 4888

I have two function one adds items to cart and one removes.

I am thinking the problem is my URL request is not being formed right. So I would appreciate someone who is more experienced than me to explaining to me what the expected URL should be.

I am creating my URL like this,

url(r'^add/(d+)', views.add_to_cart, name='add_to_cart'),  
    url(r'^remove/(d+)', views.remove_from_cart, name='remove_from_cart'),
    url(r'^cart/', views.cart, name='cart'),

The the link to add items to the cart is in a base.html file and looks like this,

  {% if request.user.is_authenticated %}
         <span class="storefront_add_to_cart">
             <a href="{% url 'add_to_cart' book.id %}">[Add to Cart]</a>
         </span>
         {% endif %}

So when you add or remove an item from the cart it calls the respective functions.

Views.py

def add_to_cart(request,book_id):
        if request.user.is_authenticated():
            try:
                book = Book.objects.get(pk=book_id)
            except ObjectDoesNotExist:
                pass
            else :
                try:
                    cart = Cart.objects.get(user = request.user, active = True)
                except ObjectDoesNotExist:
                    cart = Cart.objects.create(user = request.user)
                    cart.save()
                    cart.add_to_cart(book_id)
                    return redirect('cart')
                else:
                    return redirect('index')


def remove_from_cart(request, book_id):
    if request.user.is_authenticated():
        try:
            book = Book.objects.get(pk = book_id)
        except ObjectDoesNotExist:
            pass 
        else:
            cart = Cart.objects.get(user = request.user, active = True)
            cart.remove_from_cart(book_id)
        return redirect('cart')
    else:
        return redirect('index')

When I click add to cart the url looks like this (which gives me the error)

http://localhost:8000/store/add/4

When I click remove from cart the url looks like this but I don’t get any errors. (The item in the cart stays and will not remove.)

http://localhost:8000/store/cart/%7B%20url%20'remove_from_cart'%20item.book.id%20%%7D

And in case it helps here is the respective models in models.py

class Cart(models.Model):
    user = models.ForeignKey(User)
    active = models.BooleanField(default=True)
    order_date = models.DateField(null=True)
    payment_type = models.CharField(max_length=100, null=True)
    payment_id = models.CharField(max_length=100, null=True)

    def __unicode__(self): 
            return "%s" % (self.user)

    def add_to_cart(self, book_id):
        book = Book.objects.get(pk=book_id)
        try:
            preexisting_order = BookOrder.objects.get(book=book, cart=self)
            preexisting_order.quantity += 1
            preexisting_order.save()
        except BookOrder.DoesNotExist:
            new_order = BookOrder.objects.create(
                book=book,
                cart=self,
                quantity=1
                )
            new_order.save()

            def __unicode__(self):
                return "%s" % (self.book_id)


    def remove_from_cart(self, book_id):
        book = Book.objects.get(pk=book_id)
        try:
            preexisting_order = BookOrder.objects.get(book=book, cart=self)
            if preexisting_order.quantity > 1:
                preexisting_order.quantity -= 1
                preexisting_order.save()
            else:
                preexisting_order.delete()
        except BookOrder.DoesNotExist:
            pass
Asked By: wuno

||

Answers:

You should check the type of book_id. It will be ‘unicode’. Therefore the comparison Book.objects.get(pk=book_id) will not work.

You need to type cast it to integer.

use: book_id = int(book_id)

before

book = Book.objects.get(pk=book_id)

Hope it helps.

Answered By: DragonSlayer

I think the problem is with the indentations here.

def add_to_cart(request,book_id):
    if request.user.is_authenticated():
        try:
            book = Book.objects.get(pk=book_id)
        except ObjectDoesNotExist:
            pass  
        else :
            try:
                cart = Cart.objects.get(user = request.user, active = True)
            except ObjectDoesNotExist:
                cart = Cart.objects.create(user = request.user)
                cart.save()
            cart.add_to_cart(book_id)
        return redirect('cart')
    else:
        return redirect('index')
Answered By: ruddra

Lets tackle this one at at time.

To start off with, you need to use the login_required decorator; you should also not accept invalid books to be added to the cart (which you are currently checking at the database level, and this error is not being displayed to the customer).

from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404

@login_required
def add_to_cart(request,book_id):
    book = get_object_or_404(Book, pk=book_id)
    cart,created = Cart.objects.get_or_create(user=request.user, active=True)
    cart.add_to_cart(book_id)
    return redirect('cart')

Next, you need to fix your template where you are generating the link to remove items from your cart. Your link should be:

<a href="{% url 'remove_from_cart' args=(item.book.id,) %}">Remove item</a>

In your models, you have two __unicode__ methods, I assume this is an error in copy-paste, otherwise you need to remove the second one, which won’t work anyway since its indented into the add_to_cart method, from your models.py.

You don’t need that method anyway, you should keep the entire logic in your views. Here is the revised method:

from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
from django.contrib import messages

from .models import Cart, BookOrder, Book

@login_required
def add_to_cart(request,book_id):
    book = get_object_or_404(Book, pk=book_id)
    cart,created = Cart.objects.get_or_create(user=request.user, active=True)
    order,created = BookOrder.objects.get_or_create(book=book,cart=cart)
    order.quantity += 1
    order.save()
    messages.success(request, "Cart updated!")
    return redirect('cart')
Answered By: Burhan Khalid
def AddToCart (request, id):

    menu = product.objects.get(id=id)
    user= userModel.objects.get(id=request.user.id)
    
    if item.objects.get(ProductID = id,user = request.user.id):
        update = item.objects.get(ProductID=id,user=request.user.id)
        update.quantity += 1
        update.save()
        
    
    else :
        add =item(ProductID=menu, quantity=1, user=register)
        add.save()
        
    

    return redirect(Home)
Answered By: mehrdad
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.