Django饮品配方工具:如何按份数计算原料量并保留原始值
饮品配方份数计算:基于原始值的实现方案
问题核心
当前代码的问题是每次计算时会直接使用页面上显示的当前数值作为基数,导致多次修改份数后,计算结果是基于上一次的计算值而非原始配方量(比如原始25ml,选2份变成50ml,再选3份会算出150ml,而正确结果应该是75ml)。要解决这个问题,关键是把原始配方量单独存储,每次计算都基于这个原始值。
实现方案
最直接的方式是利用HTML的自定义data-*属性,把原始用量存储在每个原料数量元素中,每次计算时从这个属性读取原始值,再乘以份数得到新值。
步骤1:修改Django模板的HTML
把原来重复的id='amount'改成class(id不能重复),并添加data-original-amount属性存储原始配方量:
<table class='cocktail_ingredients my-5'> <tr> <th> <h2> INGREDIENTS </h2> </th> <th> <h2> ML </h2> </th> </tr> {% for ingredient in drink.get_ingredients %} <tr> <td> {% if ingredient.ingredient_rum %} {{ingredient.ingredient_rum}} {% else %} {{ingredient.ingredient_name}} {% endif %}</td> <!-- 添加data属性存储原始值,用class代替重复id --> <td class='amount' data-original-amount="{{ingredient.ingredient_amount}}"> {{ingredient.ingredient_amount}}</td> </tr> {% endfor %} </table>
步骤2:修改JS/JQuery代码
每次计算时从data-original-amount属性读取原始值,而非当前显示的文本,同时优化输入验证逻辑:
$(document).ready(function() { // 监听份数输入框的所有输入场景(keyup+change) $('#serves').on('keyup change', function() { var serves = $(this).val(); // 输入不合法时,恢复显示原始值 if (!serves || isNaN(serves) || serves <= 0) { $('.amount').each(function() { var originalAmount = $(this).data('original-amount'); $(this).text(originalAmount); }); return; } // 转换为数字类型 serves = parseFloat(serves); // 遍历所有原料,基于原始值计算新用量 $('.amount').each(function() { var originalAmount = parseFloat($(this).data('original-amount')); var newAmount = originalAmount * serves; // 保留一位小数,可根据需求调整精度 $(this).text(newAmount.toFixed(1)); }); }); });
关键改进点
- 原始值持久存储:通过
data-original-amount把原始配方量和DOM元素绑定,不会因为页面内容更新丢失 - 输入验证更严谨:处理空值、非数字、负数/零的情况,此时自动恢复显示原始值
- 计算逻辑准确:每次都基于原始值计算,避免多次修改份数导致的累积错误
- 事件覆盖全面:同时监听
keyup和change事件,覆盖手动输入、粘贴、下拉选择等所有输入场景
内容的提问来源于stack exchange,提问作者Thomas Doll-Datema
相关产品推荐
相关产品推荐

