Этот вопрос закрыт для ответов, так как повторяет вопрос Django session: Object of type is not JSON serializable?
@amitabha

Django — Как сделать корзину и избранное на основе сессии, чтобы они работали асинхронно друг от друга?

Захотел сделать корзину и избранное на основе сессии.
Когда я сделал избранное, я начал получать странные ошибки:
TypeError at /cart/
    Object of type Decimal is not JSON serializable
    Request Method:	GET
    Request URL:	http://127.0.0.1:8000/cart/
    Django Version:	4.0.4
    Exception Type:	TypeError
    Exception Value:	
    Object of type Decimal is not JSON serializable

Но проблема не в том, о чем пишет ошибка: На самом деле он просто не может сериализовать пустое поле:
allow_nan   
    True
    check_circular  
    True
    cls 
    <class 'json.encoder.JSONEncoder'>
    default 
    None
    ensure_ascii    
    True
    indent  
    None
    kw  
    {}
    obj 
    {'cart': {'2': {'price': Decimal('123123.12'),
                    'product': <Product: test1>,
                    'quantity': 2,
                    'total_price': Decimal('246246.24'),
                    'update_quantity_form': <CartAddProductForm bound=False, valid=Unknown, fields=(quantity;update)>}},
     'favorites': {}}
    separators  
    (',', ':')
    skipkeys    
    False
    sort_keys   
    False

Как, например, тут, пустое "Избранное". И притом, если товары будут одновременно и в избранном, и в корзине, то все будет нормально.
Код корзины:
from decimal import Decimal
from django.conf import settings
from main.models import Product


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()
        # получаем товары и добавляем их в корзину
        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 __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
        if quantity == 0:
            del self.cart[product_id]
        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()

Код Избранного:
from django.conf import settings
from main.models import Product


class Favorites(object):

    def __init__(self, request):

        self.session = request.session
        favorites = self.session.get(settings.FAVORITES_SESSION_ID)
        if not favorites:
            favorites = self.session[settings.FAVORITES_SESSION_ID] = {}
        self.favorites = favorites

    def __len__(self):
        Fsum = 0
        for item in self.favorites.values():
            Fsum += 1
        return Fsum

    def __iter__(self):
        product_ids = self.favorites.keys()
        products = Product.objects.filter(id__in=product_ids)
        favorites = self.favorites.copy()
        for product in products:
            favorites[str(product.id)]['product'] = product
        for item in favorites.values():
            yield item

    def remove(self, product):
        product_id = str(product.id)
        if product_id in self.favorites:
            del self.favorites[product_id]
            self.save()

    def add(self, product):
        product_id = str(product.id)
        if product_id not in self.favorites:
            self.favorites[product_id] = {'product_id': product_id}
        else:
            del self.favorites[product_id]
        self.save()

    def save(self):
        self.session.modified = True

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

Как тут видно, я использовал разные SESSION_ID.
Вопрос: Как сделать так, чтобы и корзина, и избранное, могли работать независимо друг от друга?
  • Вопрос задан
  • 111 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Вопрос закрыт для ответов и комментариев

Потому что уже есть похожий вопрос.
Похожие вопросы