[Answered ]-Add products with different sizes and price to Cart | Django

1👍

after 2 days of struggling finally I found the solution

for adding products with different sizes you have to pass the size model id to session instead of the product id

shop/models.py

class ProductSizes(models.Model):
  name = models.CharField(max_length=50)
  price = models.IntegerField()
  off_price = models.IntegerField(blank=True , null=True)
  picture = models.ImageField(upload_to="products/%Y/%m/%d" )
  product = models.ForeignKey("Product" ,  on_delete=models.CASCADE )
  


class Product(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True)
    picture = models.ImageField(upload_to="products/%Y/%m/%d" )
    picture2 = models.ImageField(upload_to="products/%Y/%m/%d" , blank=True)
    picture3 = models.ImageField(upload_to="products/%Y/%m/%d" , blank=True)
    picture4 = models.ImageField(upload_to="products/%Y/%m/%d" , blank=True)
    price = models.IntegerField()
    available = models.BooleanField(default=True)
    category = models.ForeignKey(Category ,on_delete=models.CASCADE , blank=True ,null=True )
    slug = models.SlugField(max_length=100 , db_index=True  , unique=True)
    tags = TaggableManager(blank=True)
    is_amazing = models.BooleanField(default=False)
    amazing_till = models.CharField(max_length=10 , null=True , blank=True)
    off_price = models.IntegerField(blank=True , null=True)
    brand = models.ForeignKey(Brand ,on_delete=models.CASCADE , blank=True ,null=True )
    created_at = models.DateField(auto_now_add=True)
    update_at = models.DateField(auto_now=True)

    def get_absolute_url(self):
      return reverse('get.single.product', kwargs={'slug': self.slug})


    class Meta:
        ordering=("name",) 
        index_together = (('id' , 'slug'),)

cart/cart.py

from django.conf import settings
from shop.models import Product, ProductSizes



class Cart:
    def __init__(self,request):
        self.session = request.session
        cart = self.session.get(settings.CART_SESSION_ID)
        if not cart:
            cart = self.session[settings.CART_SESSION_ID] = {}
            
        self.cart = cart
        
    # add to cart
    def add(self,product,size_,quantity=1,override_quantity=False):
        size_id = str(size_.id)
        if size_id not in self.cart:
            if size_.price:
                self.cart[size_id] = {'quantity': 0, 'price': size_.price}
            elif size_.off_price:
                self.cart[size_id] = {'quantity': 0, 'price': size_.off_price}

        self.cart[size_id]['quantity'] += quantity
        self.save()
  

        self.save()
    
    def save(self):
        self.session.modified = True
    
    #remove from cart
    def remove(self,size_):
        product_id = str(size_.id)
        if product_id in self.cart:
            del self.cart[product_id]
            self.save()
    
    def __iter__(self):
        sizes_ids = self.cart.keys()
        products = ProductSizes.objects.filter(id__in=sizes_ids)
        
        cart = self.cart.copy()
        for size in products:
            cart[str(size.id)]['size'] = size
        
        for item in cart.values():
            item['total_price'] = item['price'] * item['quantity']
            yield item

    def __len__(self):
        return sum(item['quantity'] for item in self.cart.values())
    
    def get_total_price(self):
        return sum(item['price'] * item['quantity'] for item in self.cart.values())
        
    
    def clear(self):
        del self.session[settings.CART_SESSION_ID]
        self.save()
    

cart/views.py

@require_POST
def cart_add(request , product_id , size):
    cart = Cart(request)
    product = Product.objects.get(id=product_id)
    size_ = get_object_or_404(ProductSizes , id=size)

    form = CartAddProductForm(request.POST)
    if form.is_valid():
        cd = form.cleaned_data
        cart.add(product=product , quantity=cd['quantity'] ,size_=size_, override_quantity=cd['override'] )
    return redirect("home")

The template

{% block cart %}
<div class="shopping-cart-wrap">
  <a href="#"> <span class="cart-total-amunt">{{cart.get_total_price}} تومان</span><i class="icon-shopping-bag2 float-left"></i><span class="cart-total">{{cart|length}}</span></a> 
    <ul class="mini-cart">
        {% for item in cart %}
            <li class="cart-item">
                <div class="cart-image">
                     <a href="{% url 'get.single.product' item.size.product.slug %}"><img alt="" src="/media/{{item.size.product.picture}}" width="80" height="80"></a>  

                </div> 
                <div class="cart-title">
                    <a href="single-product.html">
                        <h4>{{item.size.name}}</h4>
                    </a>
                    <div class="quanti-price-wrap">
                        <span class="quantity">{{item.quantity}} ×</span>
                        <div class="price-box"><span class="new-price">{{item.price}} تومان</span></div>
                    </div>
                    <a class="{% url 'cart.remove' item.size.id %}" href="#"><i class="icon-x"></i></a>
                </div>
            </li>
        {% endfor %}
  
        <li class="subtotal-box">
            <div class="subtotal-title">
                <h3>جمع کل :</h3><span>{{cart.get_total_price}} تومان</span>
            </div>
        </li>
        <li class="mini-cart-btns">
            <div class="cart-btns">
                <a href="{% url 'cart.detail' %}">مشاهده سبد</a>
                <a href="{% url 'order.create' %}">پرداخت</a>
            </div>
        </li>
    </ul>
</div>
{% endblock cart %}

 

Leave a comment