Django序列化JSON传前端JS读取amount属性报TypeError问题咨询
报错根因
你用「主键值减1作为数组索引」的逻辑完全不可靠,触发Uncaught TypeError: Cannot read properties of undefined (reading 'amount')的常见场景有这几个:
- 数据库中删除过历史产品记录,主键不连续。比如删除过pk=1的产品后,现存产品pk从2开始,选中pk=2时计算出的索引是1,但实际数组里只有1条数据、有效索引是0,取到的就是undefined
- 查询集返回结果没有严格按pk升序排列,数组元素顺序和pk值没有对应关系
- 下拉框存在空值默认选项,选中时拿到的value是空字符串,减1后得到NaN,用NaN当索引取数组元素必然返回undefined
修复方案
核心思路是不要靠数组索引匹配数据,直接用产品主键作为键做映射匹配,从根源避免索引对应错误。
后端代码调整
修改views.py里的序列化逻辑,提前把数据处理成主键为键的映射结构,不用前端再做索引计算:
from django.core import serializers import json @login_required def add_invoice(request): form = InvoiceForm(request.POST or None) # 读取原始序列化数据 raw_inventory = json.loads(serializers.serialize("json", Inventory.objects.all())) # 构造以产品主键为键的映射字典 data = {str(item["pk"]): item["fields"] for item in raw_inventory} total_invoices = Invoice.objects.count() queryset = Invoice.objects.order_by('-invoice_date')[:6] if form.is_valid(): form.save() messages.success(request, 'Successfully Saved') return redirect('/invoice/list_invoice') context = { "form": form, "title": "New Invoice", "total_invoices": total_invoices, "queryset": queryset, "data": json.dumps(data), } return render(request, "entry.html", context)
前端代码调整
修改JS逻辑,直接拿选中项的主键值匹配对应产品数据,同时加空值判断避免异常:
const data = JSON.parse(document.getElementById('hello-data').textContent); const productSelect = document.getElementById('id_line_one'); const priceInput = document.getElementById('id_line_one_unit_price'); productSelect.addEventListener('change', function() { const selectedProductPk = this.value; // 匹配到对应产品数据就填充单价,否则清空输入框 if (selectedProductPk && data[selectedProductPk]) { priceInput.value = data[selectedProductPk].amount; } else { priceInput.value = ''; } });
如果你不想调整后端结构,也可以在前端拿到原始数组后,每次选中时遍历数组匹配对应pk的项,但产品数量较多时,提前构造主键映射的性能更好。
内容的提问来源于stack exchange,提问作者perpetualdarkness
相关产品推荐
相关产品推荐

