我可以使用现有的 oscar oscar-api 对象模型来实现单项购物篮吗?
Can I use the existing oscar oscar-api object model to implement a single-item only basket?
我正在处理修改后的结帐视图,该视图接受单一 product/price/quantity、客户信息(姓名、地址、电子邮件)和运费。
问题:我可以为此使用现有的 django-oscar-api 方法吗?换句话说,我想强制执行一个仅包含单一产品的篮子模型,并在进行更新时使用 (LIFO) 后进先出。
这是我的第一次尝试:
# This method is a hybrid of two oscarapi methods
# 1. oscarapi/basket/add-product
# 2. oscarapi/checkout
# It only allows one product to be added to the
# basket and immediately freezes it so that the
# customer can checkout
def post(self, request, format=None):
# deserialize the product from json
p_ser = self.add_product_serializer_class(
data=request.data['addproduct'], context={'request': request})
if p_ser.is_valid():
# create a basket
basket = operations.get_basket(request)
# load the validate the product
product = p_ser.validated_data['url']
# load the validated quantity
quantity = p_ser.validated_data['quantity']
# load any options
options = p_ser.validated_data.get('options', [])
#validate the basket
basket_valid, message = self.validate(
basket, product, quantity, options)
if not basket_valid:
return Response(
{'reason': message},
status=status.HTTP_406_NOT_ACCEPTABLE)
# add the product to the validated basket
basket.add_product(product, quantity=quantity, options=options)
# apply offers
operations.apply_offers(request, basket)
###### from oscarapi.views.checkout
# deserialize the checkout object and complete the order
co_data = request.data['checkout']
co_data['basket'] = "http://127.0.0.1:8000/oscar-api/baskets/"+str(basket.pk)+"/"
c_ser = self.checkout_serializer(
data=co_data, context={'request': request})
if c_ser.is_valid():
order = c_ser.save()
basket.freeze()
o_ser = self.order_serializer_class(
order, context={'request': request})
oscarapi_post_checkout.send(
sender=self, order=order, user=request.user,
request=request, response=response)
return response.Response(o_ser.data)
return response.Response(c_ser.errors, status.HTTP_406_NOT_ACCEPTABLE)
原始答案是肯定的。
现在...
您肯定已经注意到,使用 oscar-api
实现此任务并非易事。 oscar-api
它只是没有实现对这些功能的思考。它是一个 REST API,没有别的。
最简单的方法...
我建议更深入地分叉 basket
应用程序并覆盖 Basket.add_product
方法以确保您想要的,简单。
0f course this is only valid if you own the backend implementation or have some decision power over it.
看这个:
class Basket(AbstractBasket):
# ...
def add_product(self, product, quantity=1, options=None):
if quantity > 1:
# Throw an error, set it to 1, is up to you
# Remove all lines.
self.flush()
# Do as usual.
super(Basket, self).add_product(product, quantity, options)
非常非常简单!
我正在处理修改后的结帐视图,该视图接受单一 product/price/quantity、客户信息(姓名、地址、电子邮件)和运费。
问题:我可以为此使用现有的 django-oscar-api 方法吗?换句话说,我想强制执行一个仅包含单一产品的篮子模型,并在进行更新时使用 (LIFO) 后进先出。
这是我的第一次尝试:
# This method is a hybrid of two oscarapi methods
# 1. oscarapi/basket/add-product
# 2. oscarapi/checkout
# It only allows one product to be added to the
# basket and immediately freezes it so that the
# customer can checkout
def post(self, request, format=None):
# deserialize the product from json
p_ser = self.add_product_serializer_class(
data=request.data['addproduct'], context={'request': request})
if p_ser.is_valid():
# create a basket
basket = operations.get_basket(request)
# load the validate the product
product = p_ser.validated_data['url']
# load the validated quantity
quantity = p_ser.validated_data['quantity']
# load any options
options = p_ser.validated_data.get('options', [])
#validate the basket
basket_valid, message = self.validate(
basket, product, quantity, options)
if not basket_valid:
return Response(
{'reason': message},
status=status.HTTP_406_NOT_ACCEPTABLE)
# add the product to the validated basket
basket.add_product(product, quantity=quantity, options=options)
# apply offers
operations.apply_offers(request, basket)
###### from oscarapi.views.checkout
# deserialize the checkout object and complete the order
co_data = request.data['checkout']
co_data['basket'] = "http://127.0.0.1:8000/oscar-api/baskets/"+str(basket.pk)+"/"
c_ser = self.checkout_serializer(
data=co_data, context={'request': request})
if c_ser.is_valid():
order = c_ser.save()
basket.freeze()
o_ser = self.order_serializer_class(
order, context={'request': request})
oscarapi_post_checkout.send(
sender=self, order=order, user=request.user,
request=request, response=response)
return response.Response(o_ser.data)
return response.Response(c_ser.errors, status.HTTP_406_NOT_ACCEPTABLE)
原始答案是肯定的。
现在...
您肯定已经注意到,使用 oscar-api
实现此任务并非易事。 oscar-api
它只是没有实现对这些功能的思考。它是一个 REST API,没有别的。
最简单的方法...
我建议更深入地分叉 basket
应用程序并覆盖 Basket.add_product
方法以确保您想要的,简单。
0f course this is only valid if you own the backend implementation or have some decision power over it.
看这个:
class Basket(AbstractBasket):
# ...
def add_product(self, product, quantity=1, options=None):
if quantity > 1:
# Throw an error, set it to 1, is up to you
# Remove all lines.
self.flush()
# Do as usual.
super(Basket, self).add_product(product, quantity, options)
非常非常简单!