我尝试通过开发Django电子商务网站来提高我的Django知识(我是初学者)。
我想要两种类型的购物车,一种名为购物车,另一种名为composed_cart。
我对composed_cart有错误。
当我尝试显示购物车时,我遇到了以下错误:Object of type 'Decimal' is not JSON serializable
对于我添加到composed_cart类,我使用以下代码:
composed_cart.py:
class ComposedCart(object):
def __init__(self, request):
self.session = request.session
composed_cart = self.session.get('composed_cart')
if not composed_cart:
composed_cart = self.session['composed_cart'] = {}
self.composed_cart = composed_cart
def add_composed(self, product, quantity=1):
product_id = str(product.id)
if product_id not in self.composed_cart:
self.composed_cart[product_id] = {'quantity': 1,'price': str(product.prix_unitaire), 'tva': str(product.taux_TVA.taux_applicable)}
else:
self.composed_cart[product_id]['quantity'] += quantity #Ajoute +1 à la quantité et met à jour le dictionnaire contenant la quantité. += signifie ajoute à la valeur initiale de quantité.
self.save()
def save(self):
self.session['composed_cart'] = self.composed_cart
self.session.modified = True
def remove(self, product): #Supprimer le produit, quelque soit la quantité.
product_id = str(product.id)
if product_id in self.composed_cart:
del self.composed_cart[product_id]
self.save()
def remove_one(self, product, quantity=1): #Méthode permettant de supprimer une unité du produit.
product_id = str(product.id)
if product_id in self.composed_cart: #Si le produit est dans le panier
if self.composed_cart[product_id]['quantity'] > 1: #Et si la quantité de ce produit est supérieure à 1
self.composed_cart[product_id]['quantity'] -= quantity #On enlève la quantité par défaut, d'est à dire 1.
else:
del self.composed_cart[product_id] #Si la quantité du produit est égale à 1 alors et que l'on veut enlever une unité, cela veut dire que l'on supprimer le produit.
self.save()
def __iter__(self):
product_ids = self.composed_cart.keys() #Sélectionne les différentes clés du dictionnaires, dans notre cas l'id du produit, la quantité, le prix.
products = Article.objects.filter(id__in=product_ids) #On filtre sur les IDs présents dans le dictionnaire du panier.
for product in products:
self.composed_cart[str(product.id)]['product'] = product
for item in self.composed_cart.values():
item['price'] = Decimal(item['price'])
item['tva'] = Decimal(item['tva'])
item['total_price'] = item['price'] * item['quantity']
item['total_item_tva'] = item['total_price'] - item['total_price'] / item['tva'] #Calcul du total de TVA par article.
yield item
def __len__(self):
return sum(item['quantity'] for item in self.composed_cart.values())
def get_total_price(self):
return sum(Decimal(item['price']) * item['quantity'] for item in self.composed_cart.values())
def get_total_tva(self):
return sum(round(Decimal(item['total_item_tva']),2) for item in self.composed_cart.values()) #Calcul de la TVA, round(X,2), permet d'arrondir à 2 décimales après la virgule le montant de la TVA
def get_sub_total_price(self):
return sum(Decimal(item['price']) * item['quantity'] for item in self.composed_cart.values()) - sum(round(Decimal(item['total_item_tva']),2) for item in self.composed_cart.values())
def clear(self):
del self.session['composed_cart']
self.session.modified = True
我的cart.py:
class Cart(object):
def __init__(self, request):
self.session = request.session
cart = self.session.get('cart')
if not cart:
cart = self.session['cart'] = {}
self.cart = cart
def add(self, product, quantity=1):
product_id = str(product.id)
if product_id not in self.cart:
self.cart[product_id] = {'quantity': 1,'price': str(product.prix_unitaire), 'tva': str(product.taux_TVA.taux_applicable)}
else:
self.cart[product_id]['quantity'] += quantity #Ajoute +1 à la quantité et met à jour le dictionnaire contenant la quantité. += signifie ajoute à la valeur initiale de quantité.
self.save()
def save(self):
self.session['cart'] = self.cart
self.session.modified = True
def remove(self, product): #Supprimer le produit, quelque soit la quantité.
product_id = str(product.id)
if product_id in self.cart:
del self.cart[product_id]
self.save()
def remove_one(self, product, quantity=1): #Méthode permettant de supprimer une unité du produit.
product_id = str(product.id)
if product_id in self.cart: #Si le produit est dans le panier
if self.cart[product_id]['quantity'] > 1: #Et si la quantité de ce produit est supérieure à 1
self.cart[product_id]['quantity'] -= quantity #On enlève la quantité par défaut, d'est à dire 1.
else:
del self.cart[product_id] #Si la quantité du produit est égale à 1 alors et que l'on veut enlever une unité, cela veut dire que l'on supprimer le produit.
self.save()
def __iter__(self):
product_ids = self.cart.keys() #Sélectionne les différentes clés du dictionnaires, dans notre cas l'id du produit, la quantité, le prix.
products = Article.objects.filter(id__in=product_ids) #On filtre sur les IDs présents dans le dictionnaire du panier.
for product in products:
self.cart[str(product.id)]['product'] = product
for item in self.cart.values():
item['price'] = Decimal(item['price'])
item['tva'] = Decimal(item['tva'])
item['total_price'] = item['price'] * item['quantity']
item['total_item_tva'] = item['total_price'] - item['total_price'] / item['tva'] #Calcul du total de TVA par article.
yield item
def __len__(self):
return sum(item['quantity'] for item in self.cart.values())
def get_total_price(self):
return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values())
def get_total_tva(self):
return sum(round(Decimal(item['total_item_tva']),2) for item in self.cart.values()) #Calcul de la TVA, round(X,2), permet d'arrondir à 2 décimales après la virgule le montant de la TVA
def get_sub_total_price(self):
return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values()) - sum(round(Decimal(item['total_item_tva']),2) for item in self.cart.values())
def clear(self):
del self.session['cart']
self.session.modified = True
我的观点是添加产品:
@require_POST
def cart_add(request, product_id):
product = get_object_or_404(Article, id=product_id)
#Si le produit ajouté au panier est un article simple sans composition, alors on l'ajoute directement au panier.
if product.article_composer == False:
cart = Cart(request)
form = CartAddProductForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
next = cd['next'] # Permet d'enregistrer la page précédente et d'y retourner une fois la quantité ajoutée dans le panier.
cart.add(product=product, quantity=cd['quantity'])
return HttpResponseRedirect(next) # Redirection vers la page d'où le produit a été ajouté.
#Si l'article que l'on ajoute au panier sert à composer alors on utilise la méthode permettant de composer un article.
else:
composed_cart = ComposedCart(request)
form = ComposedCartForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
next = cd['next'] # Permet d'enregistrer la page précédente et d'y retourner une fois la quantité ajoutée dans le panier.
composed_cart.add_composed(product=product, quantity=cd['quantity'])
return HttpResponseRedirect(next)
显示我的购物车:
def cart_detail(request):
cart = Cart(request)
composed_cart = ComposedCart(request)
cart_product_form = CartAddProductForm()
return render(request, 'panier/panier.html', locals())
我不明白为什么我会得到一个TypeError。你有什么想法?如何改进我的代码以消除此错误?
提前致谢
Singertwist
答案 0 :(得分:3)
我认为您发送到locals()
的问题是paneer.html
。
locals()
是当前命名空间中所有内容的字典,其中包含无法序列化的复杂对象(即转换为简单对象,如整数或字符串)。
为了解决这个问题,请尝试将其更改为简单的内容:
return render(request, 'panier/panier.html', {'test': 'value'})
如果有效或出现其他错误,请将其更改为您需要的内容。
错误表明某些字段不是JSON可序列化的。最简单的解决方案是这样的:
cart = {
'product_id': cart.product_id,
...
}
composed_cart = {
'id': composed_cart.id,
...
}
return render(request, 'panier/panier.html', {'cart': cart, 'composed_cart': composed_cart})
即,手动序列化对象并选择模板中需要的字段。
希望它有所帮助。