如何让Django读取JavaScript动态生成的HTML列表元素?
Django 获取JS动态生成表单列表元素的问题
我需要在Django中获取表单内由JavaScript动态生成的HTML列表元素,具体场景如下:
场景说明
JS执行前的HTML代码(列表为空):
<form action="/" class="needs-validation" method="POST" novalidate> {% csrf_token %} <ul class="list-group my-4"> <li id="productListing1" class="list-group-item d-flex justify-content-between align-items-center"> </li> <li id="productListing2" class="list-group-item d-flex justify-content-between align-items-center"> </li> <li id="productListing3" class="list-group-item d-flex justify-content-between align-items-center"> </li> <li id="cart-total-price" class="list-group-item d-flex justify-content-between align-items-center"> Total: PKR-0 </li> </form>
点击计算总价按钮后,HTML更新为:
<ul class="list-group my-4"> <li id="productListing1" class="list-group-item d-flex justify-content-between align-items-center">Juice PKR-40</li> <li id="productListing2" class="list-group-item d-flex justify-content-between align-items-center">Juice PKR-40</li> <li id="productListing3" class="list-group-item d-flex justify-content-between align-items-center">Juice PKR-40</li> <li id="cart-total-price" class="list-group-item d-flex justify-content-between align-items-center">Total: PKR-120</li> </ul>
我需要让Django读取这些动态生成的列表元素,该如何操作?
已尝试方案
试过用隐藏input标签传递数据,但添加后JS计算异常,总价变成Total: PKR-NaN。
补充代码
更新列表项和计算总价的JS代码
function addItemToCart(productTitle,productPricePKR) { var itemListing=document.getElementsByClassName('list-group-item') for (var i=0;i<itemListing.length;i++) { if (itemListing[i].innerHTML.trim().length==0) { itemListing[i].innerHTML=productTitle + " " + productPricePKR break; } } } function cartTotal() { var listItems=document.getElementsByClassName('list-group-item') var total=0 for (var i=0;i<listItems.length-1;i++) { if (listItems[i].innerHTML.trim().length==0) { break; } else { var cartItemDesc=listItems[i] cartItemDesc=listItems[i].innerHTML var cartItemPrice = cartItemDesc.substring(cartItemDesc.indexOf('-') + 1); //console.log(cartItemPrice) var price=parseFloat(cartItemPrice) total=total+price } document.getElementById('cart-total-price').innerHTML="Total: PKR-" + total } }
其中productTitle为产品名称,productPricePKR为产品价格。
相关Django视图代码
def home(request): items=StockManagement.objects.all() if request.method=='POST': TotalPrice=request.POST.get('TotalPrice') ItemsBought=request.POST.getlist('mylist') firstname=request.POST['firstname'] lastname=request.POST['lastname'] print(TotalPrice,ItemsBought,firstname,lastname) InsertCheckoutEntry=Checkout(TotalPrice=TotalPrice,ItemsBought=ItemsBought,firstname=firstname,lastname=lastname) return render(request,"Home.html",context={"items":items})
解决方法
问题出在之前添加隐藏input时,可能将其放到了.list-group-item类元素内,导致JS遍历列表项时把隐藏input也当成了商品项,解析价格时出错。正确操作如下:
- 在表单内添加独立的隐藏字段
不要把隐藏input放在列表项里,避免干扰JS遍历逻辑:
<form action="/" class="needs-validation" method="POST" novalidate> {% csrf_token %} <!-- 总价隐藏字段 --> <input type="hidden" name="TotalPrice" id="total-price-input"> <!-- 商品项隐藏字段,对应3个列表位置 --> <input type="hidden" name="mylist" id="item-1-input"> <input type="hidden" name="mylist" id="item-2-input"> <input type="hidden" name="mylist" id="item-3-input"> <ul class="list-group my-4"> <li id="productListing1" class="list-group-item d-flex justify-content-between align-items-center"></li> <li id="productListing2" class="list-group-item d-flex justify-content-between align-items-center"></li> <li id="productListing3" class="list-group-item d-flex justify-content-between align-items-center"></li> <li id="cart-total-price" class="list-group-item d-flex justify-content-between align-items-center">Total: PKR-0</li> </ul> <!-- 其他表单元素(firstname、lastname等) --> </form>
- 修改JS代码,同步更新隐藏字段
在更新列表项和计算总价的同时,同步修改对应隐藏input的值:
function addItemToCart(productTitle,productPricePKR) { var itemListing=document.getElementsByClassName('list-group-item') for (var i=0;i<itemListing.length-1;i++) // 跳过总价项 { if (itemListing[i].innerHTML.trim().length==0) { itemListing[i].innerHTML=productTitle + " " + productPricePKR; // 更新对应商品项的隐藏input document.getElementById(`item-${i+1}-input`).value = `${productTitle} ${productPricePKR}`; break; } } // 添加商品后重新计算总价 cartTotal(); } function cartTotal() { var listItems=document.getElementsByClassName('list-group-item') var total=0 for (var i=0;i<listItems.length-1;i++) { if (listItems[i].innerHTML.trim().length==0) { // 清空未使用的商品项隐藏input document.getElementById(`item-${i+1}-input`).value = ""; break; } else { var cartItemDesc=listItems[i].innerHTML; var cartItemPrice = cartItemDesc.substring(cartItemDesc.indexOf('-') + 1); var price=parseFloat(cartItemPrice); total=total+price; } } document.getElementById('cart-total-price').innerHTML="Total: PKR-" + total; // 更新总价隐藏input document.getElementById('total-price-input').value = total; }
- Django接收数据
你的现有视图代码已经可以正确接收TotalPrice和ItemsBought:ItemsBought会是一个包含所有非空商品项的列表,TotalPrice为计算后的总价。
内容的提问来源于stack exchange,提问作者Muhammad Taimoor
相关产品推荐
相关产品推荐

