Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding Items To Shopping Cart Django Python

Tags:

python

django

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
like image 615
wuno Avatar asked Mar 22 '16 06:03

wuno


People also ask

What is add to cart?

The add-to-cart button is a feature of ecommerce stores that allows customers to choose items to purchase without actually completing the payment. For online stores, it lives on individual product pages, functioning as the digital equivalent of a shopping cart in a brick and mortar store.

Can you build websites with Django?

You can create your very own templates for the website using Html, CSS and JS. Modify URLS, link various pages and do a lot more with Django! For more details and information about the Django series check out their very own documentation at https://www.djangoproject.com/.


1 Answers

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')
like image 62
Burhan Khalid Avatar answered Oct 10 '22 03:10

Burhan Khalid