from django.db import models from django.conf import settings from products.models import Product from django.contrib.auth import get_user_model from django.db.models.signals import m2m_changed, pre_save from django.dispatch import receiver User = get_user_model() class CartManager(models.Manager): def new_or_get(self, request): cart_id = request.session.get("cart_id", None) qs = self.get_queryset().filter(id=cart_id) if qs.count() == 1: new_obj = False cart_obj = qs.first() if request.user.is_authenticated() and cart_obj.user is None: cart_obj.user = request.user cart_obj.save() else: cart_obj = Cart.objects.new(user=request.user) new_obj = True request.session["cart_id"] = cart_obj.id return cart_obj, new_obj def new(self, user=None, products=None): if user is not None: if user.is_authenticated(): return self.model.objects.create(user=user) return self.model.objects.create(user=None) class Cart(models.Model): user = models.ForeignKey(User, null=True, blank=True) products = models.ManyToManyField(Product, null=True, blank=True) total = models.DecimalField(default=0.00, max_digits=100, decimal_places=2) subtotal = models.DecimalField(default=0.00, max_digits=100, decimal_places=2) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) objects = CartManager() def __str__(self): return str(self.id) @receiver(m2m_changed, sender=Cart.products.through) def cart_change(sender, instance, action, **kwargs): if action in ("post_add", "post_remove", "post_clear"): print('change') prs = instance.products.all() t = 0 for i in prs: t += i.price if instance.subtotal != t: instance.subtotal = t instance.save() # cart_obj.save() @receiver(pre_save, sender=Cart) def cart_save(sender, instance, **kwargs): instance.total = float(instance.subtotal) * float(0.95) # 5% discount