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

Django ModelForm含ManyToManyField场景下如何计算订单总价

问题原因
  • Django的多对多字段依赖主表的主键ID才能建立关联,你调用calculate_total_price_obj的时候,obj还未执行数据库写入操作,没有生成id值,无法读取多对多关联的餐品数据
  • 调用form.save(commit=False)之后,表单内的多对多数据不会自动写入数据库,需要手动调用form.save_m2m()完成多对多关联数据的保存
  • 现有calculate_total_price_obj逻辑错误,obj.ordered_foods是Django的多对多管理器对象,不是餐品的价格列表,不能直接求和
  • 你修改request.POST._mutable的代码没有实际作用,可直接删除
修复代码

修改后views.py

from django.shortcuts import render
from .helpers import calculate_total_price_obj
from .forms import OrderForm

def create_order(request):
    if request.method == 'POST':
        form = OrderForm(request.POST)
        if form.is_valid():
            # 先保存基础字段到数据库,生成主键ID
            obj = form.save(commit=False)
            obj.save()
            # 保存多对多关联的餐品数据
            form.save_m2m()
            # 计算总价后二次保存订单
            obj.total_price = calculate_total_price_obj(obj)
            obj.save()
    else:
        form = OrderForm()
    return render(request, 'create_order.html', {'form': form})

修改后helpers.py

普通遍历版本:

def calculate_total_price_obj(obj) -> float:
    """
    Calculate the total_price of the order.
    This function has to be called after the Order has been created and saved.
    """
    return sum(food.price for food in obj.ordered_foods.all())

更高性能的数据库聚合版本(推荐):

from django.db.models import Sum

def calculate_total_price_obj(obj) -> float:
    return obj.ordered_foods.aggregate(total=Sum('price'))['total'] or 0.0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:15:03