TypeError: Object of type Decimal is not JSON serializable | Django

I am getting quite unusual error. I got pretty confused because of this. When I iterate over the cart items and try to view them it throws a TypeError Object of type Decimal is not JSON serializable. But if i remove the block from my templates then refresh the page and again add the same block to my templates and refresh the page it works. I have added some screenshots. Please have a look and help me out with this

cart.py

class Cart(object):
    def __init__(self, request):
        """
        Initialize the cart
        """
        self.session = request.session
        cart = self.session.get(settings.CART_SESSION_ID)

        if not cart:
            # save an empty cart in the session
            cart = self.session[settings.CART_SESSION_ID] = {}
        
        self.cart = cart

    def add(self, product, quantity=1, override_quantity=False):
        """
        Add a product to the cart or update its quantity
        """
        product_id = str(product.id)

        if product_id not in self.cart:
            self.cart[product_id] = {
                'quantity': 0,
                'price': str(product.price)
            }
        
        if override_quantity:
            self.cart[product_id]['quantity'] = quantity
        else:
            self.cart[product_id]['quantity'] += quantity
        
        self.save()
    def __iter__(self):
        """
        Iterate over the items in the cart
        and get the products from the database
        """
        product_ids = self.cart.keys()
        # get the product objects and add the o the cart
        products = Product.objects.filter(id__in=product_ids)

        cart = self.cart.copy()

        for product in products:
            cart[str(product.id)]['product'] = product
        
        for item in cart.values():
            item['price'] = Decimal(item['price'])
            item['total_price'] = item['price'] * item['quantity']
            yield item

    def get_total_price(self):
        """
        Calculate the total cost of the items in the cart
        """
        return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values())

orders.py

def order_create(request):
    cart = Cart(request)
    order = None
    address_form = AddressCheckoutForm()
    billing_address_id = request.session.get('billing_address_id', None)
    shipping_address_id = request.session.get('shipping_address_id', None)
    order, created = Order.objects.get_or_create(user=request.user, ordered=False)
    if shipping_address_id:
        shipping_address = Address.objects.get(id=shipping_address_id)
        order.shipping_address = shipping_address
        del request.session['shipping_address_id']
    if billing_address_id:
        billing_address = Address.objects.get(id=billing_address_id)
        order.billing_address = billing_address
        del request.session['billing_address_id']
    if billing_address_id or shipping_address_id:
        order.save()
    
    if request.method == 'POST':
        for item in cart:
            OrderItem.objects.create(
                order=order,
                product=item['product'],
                price=item['price'],
                quantity=item['quantity']
            )
        order.ordered = True
        order.save()
        cart.clear()
        return render(request, 'orders/order/created.html', {'order': order})
    return render(request, 'orders/order/create.html', {'cart': cart, 'address_form': address_form, 'object': order})     

create.html

<h1>Checkout</h1>
    {% if not object.shipping_address %}
        <h3>Shipping</h3>
        {% url "addresses:checkout_address_create" as checkout_address_create %}
        {% include 'address/form.html' with form=address_form next_url=request.build_absolute_uri action_url=checkout_address_create address_type='shipping' %}
    {% elif not object.billing_address %}
        <h3>Billing</h3>
        {% url "addresses:checkout_address_create" as checkout_address_create %}
        {% include 'address/form.html' with form=address_form next_url=request.build_absolute_uri action_url=checkout_address_create address_type='billing' %}
    {% else %}
        {% for item in cart %}
            {{ item.quantity }} X {{ item.product.name }}
            {{ item.total_price }}
        {% endfor %}
        <p>Total Price: {{ cart.get_total_price }}</p>
        <form action="" method="POST">
            {% csrf_token %}
            <p><input type="submit" value="Place Order"></p>
        </form>
    {% endif %}

Traceback

Internal Server Error: /order/create/
Traceback (most recent call last):
  File "/home/duke/Monday/truck-giggle/env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/duke/Monday/truck-giggle/env/lib/python3.8/site-packages/django/utils/deprecation.py", line 96, in __call__
    response = self.process_response(request, response)
  File "/home/duke/Monday/truck-giggle/env/lib/python3.8/site-packages/django/contrib/sessions/middleware.py", line 58, in process_response
    request.session.save()
  File "/home/duke/Monday/truck-giggle/env/lib/python3.8/site-packages/django/contrib/sessions/backends/db.py", line 83, in save
    obj = self.create_model_instance(data)
  File "/home/duke/Monday/truck-giggle/env/lib/python3.8/site-packages/django/contrib/sessions/backends/db.py", line 70, in create_model_instance
    session_data=self.encode(data),
  File "/home/duke/Monday/truck-giggle/env/lib/python3.8/site-packages/django/contrib/sessions/backends/base.py", line 105, in encode
    serialized = self.serializer().dumps(session_dict)
  File "/home/duke/Monday/truck-giggle/env/lib/python3.8/site-packages/django/core/signing.py", line 87, in dumps
    return json.dumps(obj, separators=(',', ':')).encode('latin-1')
  File "/usr/lib/python3.8/json/__init__.py", line 234, in dumps
    return cls(
  File "/usr/lib/python3.8/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.8/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python3.8/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Decimal is not JSON serializable
[29/Jul/2020 14:20:17] "GET /order/create/ HTTP/1.1" 500 102125

The error

code block that is raising the error

removing the block

after removing the block and refreshing the page

adding the block again

after adding the block and refreshing the page

As you can see before removing the code block the error is there, after removing it and refreshing the page and adding the code block back to the templates and refreshing the page again seems to work fine. Can you please help me out with this?

5

The problem here at this line

for product in products:
    cart[str(product.id)]['product'] = product 

product’s instance has a decimal field, the price field, which is not JSON serializable.
So to solve this error, you can add explicitly the product’s fields, you want to use in the template, into the session data to loop over.
For instance:

cart[str(product.id)]['product_name'] = product.name
cart[str(product.id)]['product_price'] = float(product.price) 

and for the price field, instead of converting it into Decimal, you can use float:

for item in cart.values():
    item['price'] = float(item['price']) 

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật