【发布时间】:2021-10-27 00:01:44
【问题描述】:
我正在创建一个无需任何注册即可处理购物的商店,但我遇到了一些问题。
我正在存储有关用户在 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"))
然后出现错误“'Product' 类型的对象不是 JSON 可序列化的”
完整的追溯:
Internal Server Error: /orders/add/
Traceback (most recent call last):
File "D:\GitHub\Ecommerce-Store\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "D:\GitHub\Ecommerce-Store\venv\lib\site-packages\django\utils\deprecation.py", line 119, in __call__
response = self.process_response(request, response)
File "D:\GitHub\Ecommerce-Store\venv\lib\site-packages\django\contrib\sessions\middleware.py", line 61, in process_response
request.session.save()
File "D:\GitHub\Ecommerce-Store\venv\lib\site-packages\django\contrib\sessions\backends\db.py", line 83, in save
obj = self.create_model_instance(data)
File "D:\GitHub\Ecommerce-Store\venv\lib\site-packages\django\contrib\sessions\backends\db.py", line 70, in create_model_instance
session_data=self.encode(data),
File "D:\GitHub\Ecommerce-Store\venv\lib\site-packages\django\contrib\sessions\backends\base.py", line 116, in encode
compress=True,
File "D:\GitHub\Ecommerce-Store\venv\lib\site-packages\django\core\signing.py", line 110, in dumps
return TimestampSigner(key, salt=salt).sign_object(obj, serializer=serializer, compress=compress)
File "D:\GitHub\Ecommerce-Store\venv\lib\site-packages\django\core\signing.py", line 172, in sign_object
data = serializer().dumps(obj)
File "D:\GitHub\Ecommerce-Store\venv\lib\site-packages\django\core\signing.py", line 87, in dumps
return json.dumps(obj, separators=(',', ':')).encode('latin-1')
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\json\__init__.py", line 238, in dumps
**kw).encode(obj)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\json\encoder.py", line 180, in default
o.__class__.__name__)
TypeError: 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
from decimal import Decimal
from store.models import Product
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
def delete(self, product):
product_id = str(product)
if product_id in self.orders:
del self.orders[product_id]
self.session.modified = True
def clear(self):
del self.session['os']
self.session.modified = True
def __iter__(self):
product_ids = self.orders.keys()
products = Product.products.filter(id__in=product_ids)
orders = self.orders.copy()
for product in products:
orders[str(product.id)]['product'] = product
for item in orders.values():
item['price'] = float(item['price'])
item['total_price'] = item['price'] * item['quantity']
yield item
def __len__(self):
return sum(item['quantity'] for item in self.orders.values())
def get_total_price(self):
return sum(float(item['price']) * item['quantity'] for item in self.orders.values())
我想知道为什么执行的类似操作不会抛出相同的错误
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
有什么解决办法吗?
【问题讨论】:
-
什么是
Product?这是一个关于序列化这个对象的问题,而大多数其他代码可能是不相关的。这将有助于显示回溯,以便我们准确了解失败的原因。 -
@tdelaney 抱歉,请稍等
-
你能分享整个回溯吗?
-
好的,等一下@bdbd
-
我不知道解决方案,但这里有一个关于 django 序列化的链接:docs.djangoproject.com/en/3.2/topics/serialization
标签: python json django django-sessions