Home > Blockchain >  I get an error [<class 'decimal.ConversionSyntax'>] in my cart, how do I fix this?
I get an error [<class 'decimal.ConversionSyntax'>] in my cart, how do I fix this?

Time:06-13

When adding an item to the cart, an error occurs InvalidOperation at /cart/ [<class 'decimal.ConversionSyntax'>].

My code:

cart..py ...............................

from decimal import Decimal
from django.conf import settings
from TeaYardApp.models import Products


class Cart(object):

    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

    def __iter__(self):
        product_ids = self.cart.keys()
        # получаем товары и добавляем их в корзину
        product = Products.objects.filter(id__in=product_ids)

        cart = self.cart.copy()
        for product in product:
            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 __len__(self):
        return sum(item['quantity'] for item in self.cart.values())

    def add(self, product, quantity=1, update_quantity=False):
        product_id = str(product.id)
        if product_id not in self.cart:
            self.cart[product_id] = {'quantity': 0,
                                     'price': str(product.price)}
        if update_quantity:
            self.cart[product_id]['quantity'] = quantity
        else:
            self.cart[product_id]['quantity']  = quantity
        self.save()

    def save(self):
        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 get_total_price(self):
        return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values())

    def clear(self):
        del self.session[settings.CART_SESSION_ID]
        self.save()

Form for adding goods to the cart,forms.py ..................................

from django import forms

PRODUCT_QUANTITY_CHOICES = [(i, str(i)) for i in range(25, 200 1, 25)]


class CartAddProductForm(forms.Form):
    quantity = forms.TypedChoiceField(
        choices=PRODUCT_QUANTITY_CHOICES,
        coerce=int)
    update = forms.BooleanField(required=False,
                                initial=False,
                                widget=forms.HiddenInput)

I don't know how fix this error,help please. ....................................

Traceback:

Traceback (most recent call last):
  File "C:\my_projects\TeaYard\venv\lib\site-packages\django\core\handlers\exception.py"
, line 55, in inner
    response = get_response(request)
  File "C:\my_projects\TeaYard\venv\lib\site-packages\django\core\handlers\base.py", lin
e 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\my_projects\TeaYard\App\cart\views.py", line 30, in cart_detail
    for item in cart:
  File "C:\my_projects\TeaYard\App\cart\cart.py", line 28, in __iter__
    item['price'] = Decimal(item['price'])
decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]

detail.html

{% extends "base.html" %}
{% load static %}

{% block title %}
Корзина покупок
{% endblock %}

{% block content %}
<h1>Корзина покупок</h1>
<table >
    <thead>
    <tr>
        <th>Картинка</th>
        <th>Товар</th>
        <th>Обновить кол-во</th>
        <th>Удалить</th>
        <th>Кол-во</th>
        <th>Цена за шт</th>
        <th>Общая стоимость</th>
    </tr>
    </thead>
    <tbody>
    {% for item in cart %}
    {% with product=item.product %}
    <tr>
        <td>
            <a href="{{ product.get_absolute_url }}">
                <img src="{% if product.image %}{{ product.image.url }}{% else %}{% static 'PDF/no_image.png' %}{% endif %}">
            </a>
        </td>
        <td>{{ product.name }}</td>
        <td>
            <form action="{% url 'cart:cart_add' product.id %}" method="post">
                {{ item.update_quantity_form.quantity }}
                {{ item.update_quantity_form.update }}
                <input type="submit" value="Обновить">
                {% csrf_token %}
            </form>
        </td>
        <td><a href="{% url 'cart:cart_remove' product.id %}">Удалить</a></td>
        <td>
            {{ item.quantity }}
        </td>
        <td >{{ item.price }}</td>
        <td >{{ item.total_price }}</td>
    </tr>
    {% endwith %}
    {% endfor %}
    <tr >
        <td>Всего</td>
        <td colspan="4"></td>
        <td >{{ cart.get_total_price }}</td>
    </tr>
    </tbody>
</table>
<p >
    <a href="{% url 'home' %}" >В магазин</a>
    <a href="#" >Оформить заказ</a>
</p>
{% endblock %}

CodePudding user response:

According traceback error happens in this line:

item['price'] = Decimal(item['price'])

It happens because item['price'] is not numeric. For example this error may happens when value of item['price'] is '' or abc.

If you using Django Rest Framework then serializers is the best way to validate input data.

If you just want to simply avoid the error, The easiest way will be to check every time item['price']'s value:

# convert to string first (to be able call isnumeric method)
price = str(item['price'])
# check if price string is numeric
if price.isnumeric()
  price = Decimal(price)
else:
  # handle bad value (raise error or whatever depending on your logic)
  raise ValueError('price must be numeric value')

CodePudding user response:

You are passing incorrect value to Decimal function. If you give i.e. empty string ("") to that function, then you will get such error. You should check what value you are putting there.

You may try this in your get_total_price function of Cart model:

def get_total_price(self):
    price = item['price'] if item['price'] else 0
    return sum(Decimal(price) * item['quantity'] for item in self.cart.values())

If problem is the same with 'quantity', then resolve it in the same way.

  • Related