Django API中如何按餐厅属性拆分购物车生成的订单
实现方案
第一步:调整模型结构
原Order模型仅支持单个订单关联一道菜品,无法满足按餐厅分组后一个订单对应多道菜品的需求,需要先做模型调整,推荐两种实现方案可选:
方案1:新增订单餐品中间表(扩展性更强)
在models.py中新增OrderItem模型,同时删除Order中原有的cart_meal单外键字段:
# 新增OrderItem模型 class OrderItem(models.Model): """订单内餐品项""" order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='order_items') cart_meal = models.ForeignKey(CartMeal, on_delete=models.CASCADE) # 后续可扩展备注、实际结算单价等自定义字段 # 修改原Order模型,删除下面这行 # cart_meal = models.ForeignKey(CartMeal, on_delete=models.CASCADE, null=True, blank=True)
方案2:直接给CartMeal加订单关联(代码更精简)
如果不需要额外扩展订单餐品属性,可以直接在CartMeal模型中新增关联订单的外键,同时删除Order中原有的cart_meal单外键字段:
# 修改CartMeal模型,新增字段 class CartMeal(models.Model): # 原有字段保留,新增下面一行 order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True, blank=True, related_name='cart_meals') # 修改原Order模型,删除下面这行 # cart_meal = models.ForeignKey(CartMeal, on_delete=models.CASCADE, null=True, blank=True)
第二步:调整视图逻辑,按餐厅分组生成订单
修改views.py中的接口方法,先把购物车中的餐品按所属餐厅分组,每个餐厅对应生成一个订单,再关联该餐厅下所有餐品:
@action(methods=['PUT'], detail=False, url_path='current_customer_cart/add_to_order') def add_cart_to_order(self, *args, **kwargs): customer = self.request.user.customer cart = Cart.objects.get(owner=customer) # 提前关联meal和restaurant,减少数据库查询次数 cart_meals = CartMeal.objects.filter(cart=cart).select_related('meal__restaurant') data = self.request.data delivery_address = data.get('address', customer.home_address) # 按餐厅分组购物车餐品 restaurant_groups = {} for cart_meal in cart_meals: restaurant = cart_meal.meal.restaurant if restaurant.id not in restaurant_groups: restaurant_groups[restaurant.id] = { 'restaurant': restaurant, 'meals': [] } restaurant_groups[restaurant.id]['meals'].append(cart_meal) # 每个餐厅生成一个独立订单 for group in restaurant_groups.values(): restaurant = group['restaurant'] # 生成订单基础信息 order = Order.objects.create( customer=customer, first_name=data['first_name'], last_name=data['last_name'], phone=data['phone'], address=delivery_address, restaurant_address=restaurant.address, ) # 根据选择的模型方案二选一执行关联逻辑 # 方案1关联逻辑:批量创建OrderItem order_items = [OrderItem(order=order, cart_meal=cm) for cm in group['meals']] OrderItem.objects.bulk_create(order_items) # 方案2关联逻辑:批量更新CartMeal的order字段 # CartMeal.objects.filter(id__in=[cm.id for cm in group['meals']]).update(order=order) # 可选:订单生成后清空购物车 # cart_meals.delete() return response.Response({"detail": "Order is created", "added": True})
内容的提问来源于stack exchange,提问作者nikitaex
相关产品推荐
相关产品推荐

