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

Django生鲜电商订单模型实现:一对多关联商品明细需求

解决方案:重构订单模型并实现Admin表格式明细展示

一、模型结构重构

将原有单一订单模型拆分为订单主表和订单明细两个模型,实现一对多关联:

# 商品详情模型保持不变
class ProductDetails(models.Model):
    name= models.CharField(max_length=100)
    price= models.FloatField()
    mrp= models.FloatField()
    main_img = models.ImageField(upload_to='product_img')
    img1 = models.ImageField(upload_to='product_img')
    img2 = models.ImageField(upload_to='product_img')
    img3 = models.ImageField(upload_to='product_img')
    category = models.ForeignKey(Category, related_name='produits', on_delete=models.CASCADE)
    subcategory = models.ForeignKey(SubCategory, related_name='produits', on_delete=models.CASCADE)
    product_details = RichTextField(blank=True, null=True)
    trending = models.BooleanField(default=False)
    
    def __str__(self):
        return self.name

# 订单主表:存储订单整体信息
class Order(models.Model):
    order_id = models.CharField(max_length=100, unique=True, default="")
    customer_name = models.ForeignKey(User, related_name='orders', on_delete=models.CASCADE)  # 修正原拼写错误
    date = models.DateTimeField(auto_now_add=True)  # 自动生成订单创建时间
    address = models.CharField(max_length=500)
    mobile_no = models.CharField(max_length=12)
    order_state_list = [
        ('pending', 'Pending'),
        ('cancelled', 'Cancelled'),
        ('confirm', 'Confirm'),
        ('on_the_way', 'On the way'),    
        ('delivered', 'Delivered'),    
    ]
    order_status = models.CharField(max_length=50, choices=order_state_list, default="pending")

    payment_state_list = [
        ('pending', 'Pending'),
        ('cancelled', 'Cancelled'),
        ('confirm', 'Confirm') 
    ]
    payment_status = models.CharField(max_length=50, choices=payment_state_list, default="pending")
    transaction_id = models.CharField(max_length=100)

    def get_total_cost(self):
        # 实时汇总订单所有明细的总金额
        return sum(item.get_item_total() for item in self.order_items.all())

    def __str__(self):
        return f"Order {self.order_id} - {self.customer_name.username}"

# 订单明细:存储单个商品的购买信息
class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name='order_items', on_delete=models.CASCADE)
    product = models.ForeignKey(ProductDetails, related_name='order_items', on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)
    price = models.FloatField()  # 保存下单时的商品价格,避免后续价格变动影响历史订单

    def get_item_total(self):
        # 计算单个明细的总价
        return self.price * self.quantity

    def __str__(self):
        return f"{self.quantity} x {self.product.name}"

二、Django Admin配置实现表格式明细展示

使用TabularInline将订单明细嵌入订单编辑页面,实现类似Odoo One2Many的表格式编辑效果:

from django.contrib import admin
from .models import Order, OrderItem, ProductDetails

# 定义订单明细内联组件
class OrderItemInline(admin.TabularInline):
    model = OrderItem
    extra = 1  # 默认显示1个空的明细输入行
    fields = ('product', 'quantity', 'price')
    readonly_fields = ('price',)  # 自动填充商品价格时设为只读

    # 自动填充下单时的商品当前价格
    def save_model(self, request, obj, form, change):
        if not obj.price:
            obj.price = obj.product.price
        super().save_model(request, obj, form, change)

# 配置订单Admin页面
@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
    list_display = ('order_id', 'customer_name', 'date', 'order_status', 'payment_status', 'get_total_cost')
    inlines = [OrderItemInline]  # 关联明细内联组件
    readonly_fields = ('date', 'get_total_cost')  # 禁止修改创建时间和总金额

# 商品详情Admin保持原有配置
@admin.register(ProductDetails)
class ProductDetailsAdmin(admin.ModelAdmin):
    list_display = ('name', 'price', 'mrp', 'category', 'trending')

三、关键注意事项

  • 数据迁移:修改模型后执行python manage.py makemigrations和python manage.py migrate更新数据库,原有订单数据需手动迁移或编写迁移脚本。
  • 订单ID生成:可在Order的save方法中自动生成唯一订单ID(如时间戳+随机字符串),避免手动输入重复。
  • 价格一致性:OrderItem的price字段保存下单时的商品价格,确保历史订单金额不受后续商品调价影响。
  • 总金额优化:若需频繁查询订单总金额,可在Order中添加total_cost字段,通过信号或保存方法自动更新,替代实时计算。

内容的提问来源于stack exchange,提问作者Chetan Rathod

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:05:26