TypeError: Объект типа 'Product' не является сериализуемым в JSON

Я создаю магазин, который может обрабатывать покупки без какой-либо регистрации, но у меня есть некоторые проблемы.

Я храню данные о товарах, которые пользователь добавил в корзину в сессиях django и пытаюсь создать аналогичную систему, которая будет хранить заказы, которые сделал пользователь.

Это представление, которое выполняется после завершения всех платежей:

#I am not pasting the imports, all fine with them

basket = Basket(request)
orders = Orders(request)

 ### We are looping through the all items we are storing in basket to create for each one, single order
 for basketitem in basket:
                    #This order is automatically created for admin, just ignore it, it's working fine
                    order = Order.objects.create(user_id=user_id, product=basketitem['product'], size=basketitem['size'], quantity=basketitem['quantity'], full_name=full_name, address1=address1,
                                                 address2=address2, postcode=postcode, town=town, country=country, total_paid=baskettotal, order_key=order_key, authenticated=False)

                    #This is the main problem, this is trying to get a product from database "Product" comparing id from database to id that we store in basket in django sessions
                    product = get_object_or_404(
                        Product, id=int(basketitem['productid']))

                    orders.add(product=product, quantity=basketitem['quantity'], size=basketitem['size'], full_name=full_name, address1=address1,
                               address2=address2, postcode=postcode, town=town, country=country, created=now.strftime("%d/%m/%Y %H:%M:%S"))

После этого возникает ошибка "Object of type 'Product' is not JSON serializable"

Basket.py

class Basket():
    def __init__(self, request):
        self.session = request.session
        basket = self.session.get('bt')
        if 'bt' not in request.session:
            basket = self.session['bt'] = {}
        self.basket = basket

    def add(self, product, quantity, size):
        product_id = str(product.id)

        if product_id not in self.basket:
            self.basket[product_id] = {'productid': int(product.id), 'price': int(
                product.price), 'quantity': int(quantity), 'size': int(size)}

        self.session.modified = True

Orders.py

class Orders():
    def __init__(self, request):
        self.session = request.session
        orders = self.session.get('os')
        if 'os' not in request.session:
            orders = self.session['os'] = {}
        self.orders = orders

    def add(self, product, quantity, size, full_name, address1, address2, postcode, town, country, created):
        product_id = str(product.id)

        if product_id not in self.orders:
            self.orders[product_id] = {'price': int(
                product.price), 'quantity': int(quantity), 'size': int(size), 'full_name': str(full_name),
                'address1': str(address1), 'address2': str(address2), 'postcode': str(postcode), 'town': str(town),
                'country': str(country), 'created': str(created)
            }

        self.session.modified = True

Models.py

class Product(models.Model):
    category = models.ForeignKey(
        Category, related_name='product', on_delete=models.CASCADE)
    title = models.CharField(max_length=24)
    description = models.TextField(blank=True)
    color = models.CharField(max_length=20, blank=True)
    image = models.ImageField(upload_to='images/')
    in_stock = models.BooleanField(default=False)
    promotion = models.BooleanField(default=False)
    price = models.FloatField(max_length=6)
    created = models.DateTimeField(auto_now=True)
    slug = models.SlugField(max_length=255)
    objects = models.Manager()
    products = ProductManager()

    class Meta:
        verbose_name_plural = 'Products'
        ordering = ('-created',)

    def get_absolute_url(self):
        return reverse('store:item', args=[self.slug])

    def __str__(self):
        return self.title

Интересно, почему аналогичная операция, которая выполняется, не выдает ту же ошибку

def basket_add(request):
    '''
    Handles data captured from ajax and adds product to basket,
    updates the actual amount of products in basket.
    '''
    basket = Basket(request)
    if request.POST.get('action') == 'post':
        product_id = int(request.POST.get('productid'))
        quantity = int(request.POST.get('quantity'))
        size = int(request.POST.get('size'))
        product = get_object_or_404(Product, id=product_id)
        basket.add(product=product, quantity=quantity, size=size)
        basket_quantity = basket.__len__()
        response = JsonResponse({'quantity': basket_quantity})
        return response

Есть решения?

Упомянутая вами ошибка возникает при использовании метода json encode default. Это означает, что модуль json не распознает объект Product. Django имеет встроенный механизм сериализации для сериализации объекта модели в объект JSON.

Если вы не хотите использовать способ Django для сериализации данных, вам может понадобиться определить пользовательский кодер[1] для обработки объекта Product.

[1] https://docs.python.org/3/library/json.html#encoders-and-decoders

Вернуться на верх