#python #json #django #django-sessions
Вопрос:
Я создаю магазин, который может совершать покупки без какой-либо регистрации, но у меня есть некоторые проблемы.
Я храню данные о продуктах, которые пользователь добавил в корзину в сеансах 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"))
И после этого возникает ошибка «Объект типа»Продукт» не сериализуется в формате JSON».
полная обратная связь:
Internal Server Error: /orders/add/
Traceback (most recent call last):
File "D:GitHubEcommerce-Storevenvlibsite-packagesdjangocorehandlersexception.py", line 47, in inner
response = get_response(request)
File "D:GitHubEcommerce-Storevenvlibsite-packagesdjangoutilsdeprecation.py", line 119, in __call__
response = self.process_response(request, response)
File "D:GitHubEcommerce-Storevenvlibsite-packagesdjangocontribsessionsmiddleware.py", line 61, in process_response
request.session.save()
File "D:GitHubEcommerce-Storevenvlibsite-packagesdjangocontribsessionsbackendsdb.py", line 83, in save
obj = self.create_model_instance(data)
File "D:GitHubEcommerce-Storevenvlibsite-packagesdjangocontribsessionsbackendsdb.py", line 70, in create_model_instance
session_data=self.encode(data),
File "D:GitHubEcommerce-Storevenvlibsite-packagesdjangocontribsessionsbackendsbase.py", line 116, in encode
compress=True,
File "D:GitHubEcommerce-Storevenvlibsite-packagesdjangocoresigning.py", line 110, in dumps
return TimestampSigner(key, salt=salt).sign_object(obj, serializer=serializer, compress=compress)
File "D:GitHubEcommerce-Storevenvlibsite-packagesdjangocoresigning.py", line 172, in sign_object
data = serializer().dumps(obj)
File "D:GitHubEcommerce-Storevenvlibsite-packagesdjangocoresigning.py", line 87, in dumps
return json.dumps(obj, separators=(',', ':')).encode('latin-1')
File "C:UsersuserAppDataLocalProgramsPythonPython36libjson__init__.py", line 238, in dumps
**kw).encode(obj)
File "C:UsersuserAppDataLocalProgramsPythonPython36libjsonencoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:UsersuserAppDataLocalProgramsPythonPython36libjsonencoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "C:UsersuserAppDataLocalProgramsPythonPython36libjsonencoder.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
Есть какие-нибудь решения?
Комментарии:
1. Что такое
Product
? Это вопрос о сериализации этого объекта, и большая часть другого представленного кода, скорее всего, не связана. Это помогло бы показать обратную связь, чтобы мы точно видели, что терпит неудачу.2. @tdelaney Извините, дайте мне секунду
3. Можете ли вы поделиться всей обратной связью?
4. Конечно, подожди секунду @bdbd
5. Я не знаю решения, но вот ссылка на сериализацию django: docs.djangoproject.com/en/3.2/topics/serialization
Ответ №1:
Ошибка, о которой вы упомянули, вызвана default
методом кодирования json. Это означает, что модуль json не распознает Product
объект. Django имеет встроенный механизм сериализации для сериализации объекта модели в объект JSON.
Если вы не хотите использовать способ Django для сериализации данных, вам может потребоваться определить пользовательский кодер[1] для обработки Product
объекта.
[1] https://docs.python.org/3/library/json.html#encoders-and-decoders