text: Q:
  
  Numbers saved in Django session automatically rounded down when computing item sub totals
  
  I have pricing data saved in my model like:
      price = models.DecimalField(max_digits=12, decimal_places=4, default=None)
  
  When I render the numbers, they show up as expected: 12.0, 10.75 etc. When I attempt to calculate totals and subtotals for items in my cart, it rounds down anything with a decimal point. So when I am trying to get a total for 2 items at $10.75, it will give me $20 when I want $21.50. How can I fix this? I figure it has something to do with the way I'm saving it to sessions. Here is my sessions data:
  class Cart(object):
  
      def __init__(self, request):
          self.session = request.session
  
          if not hasattr(settings, 'CART_SESSION_KEY'):
              raise KeyNotSet('Session key identifier is missing in settings')
  
          if not hasattr(settings, 'PRODUCT_MODEL'):
              raise KeyNotSet('Product model is missing in settings')
  
          cart = self.session.get(settings.CART_SESSION_KEY)
  
          if not cart:
              is_model_set = hasattr(settings, 'USE_CART_MODELS')
              if is_model_set and settings.USE_CART_MODELS:
                  # cart =
                  pass
              else:
                  cart = self.session[settings.CART_SESSION_KEY] = {}
  
          self.cart = cart
  
      def add(self, product, price, quantity=1,):
          product_id = str(product.id)
          if product_id not in self.cart:
              self.cart[product_id] = {'price': int(price), 'quantity': 0}
  
          self.cart[product_id]['quantity'] = int(quantity)
          self.save()
  
          self.cart[product_id]['quantity'] = int(quantity)
          self.save()
  
      def save(self):
          self.session[settings.CART_SESSION_KEY] = self.cart
          self.session.modified = True
  
      def remove(self, product):
          product_id = str(product.id)
          if product_id in self.cart:
              del self.cart[product_id]
              self.save()
  
      def __iter__(self):
          product_ids = self.cart.keys()
  
          splitted = settings.PRODUCT_MODEL.split('.')
          app_label = splitted[0]
          model_name = splitted[1]
  
          try:
              model = apps.get_model(app_label, model_name)
          except LookupError:
              message = 'Model {} not found in app  {}'
              raise ModelDoesNotExist(message.format(model_name, app_label))
  
          products = model.objects.filter(id__in=product_ids)
          for product in products:
              self.cart[str(product.id)]['product'] = product
  
          for item in self.cart.values():
              item['price'] = Decimal(item['price'])
              item['total_price'] = item['price'] * item['quantity']
              yield item
  
      def __len__(self):
          return sum(item['quantity'] for item in self.cart.values())
  
      @property
      def total_price(self):
          return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values())
  
      @property
      def item_price(self):
          return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values())
  
      def clear(self):
          self.session.cart[settings.CART_SESSION_KEY] = {}
          self.session.modified = True
  
  Your help would be much appreciated!
  EDIT:
  I changed the way I was adding the numbers to my cart from an integer to decimal.decimal. I'm now receiving a type error: Object of type Decimal not json serializable. Here is the traceback:
  Traceback:
  
  File
  "C:\Program Files\Python36\lib\site-packages\django\core\handlers\exception.py" in inner
  35.
  response = get_response(request)
  
  File
  "C:\Program Files\Python36\lib\site-packages\django\utils\deprecation.py" in __call__
  97.
  response = self.process_response(request, response)
  
  File
  "C:\Program Files\Python36\lib\site-packages\django\contrib\sessions\middleware.py" in process_response
  58.
  request.session.save()
  
  File
  "C:\Program Files\Python36\lib\site-packages\django\contrib\sessions\backends\db.py" in save
  81.
  obj = self.create_model_instance(data)
  
  File
  "C:\Program Files\Python36\lib\site-packages\django\contrib\sessions\backends\db.py" in create_model_instance
  68.
  session_data = self.encode(data),
  
  File
  "C:\Program Files\Python36\lib\site-packages\django\contrib\sessions\backends\base.py" in encode
  96.
  serialized = self.serializer().dumps(session_dict)
  
  File
  "C:\Program Files\Python36\lib\site-packages\django\core\signing.py" in dumps
  87.
  return json.dumps(obj, separators=(',', ':')).encode('latin-1')
  
  File
  "C:\Program Files\Python36\lib\json\__init__.py" in dumps
  238. ** kw).encode(obj)
  
  File
  "C:\Program Files\Python36\lib\json\encoder.py" in encode
  199.
  chunks = self.iterencode(o, _one_shot=True)
  
  File
  "C:\Program Files\Python36\lib\json\encoder.py" in iterencode
  257.
  return _iterencode(o, 0)
  
  File
  "C:\Program Files\Python36\lib\json\encoder.py" in default
  180.
  o.__class__.__name__)
  
  Exception
  Type: TypeError
  at / cart / add / 4009
  Exception
  Value: Object
  of
  type
  'Decimal' is not JSON
  serializable
  
  A:
  
  It looks like you're converting the price to an int in the add() method:
  self.cart[product_id] = {'price': int(price), 'quantity': 0}
  
  That would have the effect of rounding the price down to the nearest integer.
  Since you are already converting the price to a Decimal in total_price(), you can store the value in the session as a string.
  self.cart[product_id] = {'price': str(price), 'quantity': 0}
  
  