You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 06:00:00