Reputation: 17
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
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
Reputation: 36
You could also check new_obj
for occurancies of the searched item, as far as I understand...
Upvotes: 1