etnuh
etnuh

Reputation: 17

object not saving to cart in django

I am trying to add object to cart but nothing is added. I'm pretty new to Django any help is appreciated. Also I think the error has to do with my cart_update function. In the tutorial this is how I wrote but when I was looking up this issue I found out I should be using get_object_or_404. When I tried that way I was still unsuccessful with adding objects to the cart.

models.py

from django.db import models
import os
import random
from django.db.models import Q
from django.db.models.signals import pre_save, post_save
from django.urls import reverse 
from django.shortcuts import get_object_or_404

from .utils import unique_slug_generator

def get_filename_ext(filepath):
    base_name = os.path.basename(filepath)
    name, ext = os.path.splitext(base_name)
    return name, ext

def upload_image_path(instance, filename):
    new_filename = random.randint(1,233434234)
    name, ext = get_filename_ext(filename)
    final_filename = '{new_filename}{ext}'.format(new_filename=new_filename, ext=ext)
    return "products/{new_filename}/{final_filename}".format(new_filename=new_filename, final_filename=final_filename)


class ProductQuerySet(models.query.QuerySet):
    def active(self):
        return self.filter(active=True)

    def featured(self):
        return self.filter(featured=True, active=True)

    def search(self,query):
        lookups = (Q(title__icontains=query) | 
                   Q(description__icontains=query) |
                   Q(price__icontains=query) |
                   Q(tag__title__icontains=query)
                    )
        return self.filter(lookups).distinct()

class ProductManager(models.Manager):
    def get_queryset(self):
        return ProductQuerySet(self.model, using=self._db)

    def all(self):
        return self.get_queryset().active()

    def featured(self):
        return self.get_queryset().featured()

    def get_by_id(self,id):
        qs = self.get.queryset().filter(id=id)
        if qs.count() == 1:
            return qs.first()
        return None

    def search(self,query):
        return self.get_queryset().active().search(query)

class Product(models.Model):
    title           = models.CharField(max_length=120)
    slug            = models.SlugField(blank=True,unique=True)
    description     = models.TextField()
    price           = models.DecimalField(decimal_places=2,max_digits=20,default=10.99)
    image           = models.ImageField(upload_to='gallery',null=True,blank=True)
    featured        = models.BooleanField(default=False)
    active          = models.BooleanField(default=True)
    timestamp       = models.DateTimeField(auto_now_add=True)

    objects = ProductManager()

    def get_absolute_url(self):
#        return "/products/{slug}/".format(slug=self.slug)
         return reverse("products:detail", kwargs={"slug": self.slug})

    def __str__(self):
        return self.title

def product_pre_save_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(instance)

pre_save.connect(product_pre_save_receiver, sender=Product)

In this view is my cart_update function where the issue happens.

Cart/views.py

    from django.shortcuts import render, redirect, get_object_or_404
from products.models import Product
from .models import Cart


def cart_home(request):
    cart_obj, new_obj = Cart.objects.new_or_get(request)
    products = cart_obj.products.all()

    return render(request, 'carts/home.html', {})

def cart_update(request):
    product_id = 1 #request.POST.get('product_id')
#    print(Product.objects.get(id=1))
    if product_id is not None:
        try:
            product_obj = Product.objects.get(id=product_id)
        except Product.DoesNotExist:
            print("show message to user ,Product is gone")
            return redirect("cart:home")
        cart_obj, new_obj = Cart.objects.new_or_get(request)
        if product_id in cart_obj.products.all():
            cart_obj.products.remove(product_obj)
        else:    
            cart_obj.products.add(product_obj)
    #    return redirect(product_obj.get_absolute_url())
    return redirect("cart:home")

Upvotes: 1

Views: 422

Answers (2)

Raydel Miranda
Raydel Miranda

Reputation: 14360

There are some things you could improve in your code:

1) If the product does not exist (you are "hardwiring" product_id to be 1, it might be the case) use logging, there are situations print statement won't be enough.

2) If the product is already in the cart, you remove it leaving the cart empty. You could perhaps increase quantity?

3) The condition if product_id in cart_obj.products.all() will always be False cart_obj.products.all() will return a queryset for Product not the id values, you have two options there:

if product_id in cart_obj.products.values_list("id", flat=True)

or

if product_obj in cart_obj.products.all()

4) I've not seen your 'carts/home.html' template, but in your view cart_home, you're not adding products to the view context and, by the way, since you can access products within a basket through the basket itself (they are related), you don't need the line products = cart_obj.products.all(). Just add the cart_obj to the view context

def cart_home(request):
    cart_obj, new_obj = Cart.objects.new_or_get(request)
    return render(request, 'carts/home.html', {"cart": cart_obj}) 

and write code like the following to your template:

<ul>
{% for product in cart.products.all %}
    <li>{{ product.title }}</li>
{% endfor %}
</ul>

Hope you can find the error when checking one of those, happy coding!

Upvotes: 0

crixel
crixel

Reputation: 36

You could also check new_obj for occurancies of the searched item, as far as I understand...

Upvotes: 1

Related Questions