Django中如何根据选中产品自动加载销售价格?求助
Django实现选择产品自动填充价格问题解决
我是一名Django初学者,希望实现选择产品后自动显示对应的销售价格,以下是我编写的相关代码,目前遇到问题无法推进,恳请您的帮助。感谢支持!
销售模型
class Sale(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, null=True) product = models.ForeignKey('Product', on_delete=models.CASCADE) quantity = models.PositiveIntegerField(default=1) sale_price = models.PositiveIntegerField(default=0) montant_total = models.CharField(max_length=15, default=0) def __str__(self): return self.montant_total
视图代码
def addSale(request=None): current_sale = Sale() list_user = User.objects.all().order_by('-username') list_product = Product.objects.all().order_by('-name') if request.POST: if request.POST.get('user') != "": current_sale.user = User.objects.get(id=request.POST.get('user')) if request.POST.get('product') != "": current_sale.product = Product.objects.get(id=request.POST.get('product')) if request.POST.get('quantity') != "": current_sale.quantity = request.POST.get('quantity') if request.POST.get('sale_price') != "": current_sale.sale_price = request.GET.get('price') if request.POST.get('montant_total') != "": current_sale.montant_total = request.POST.get('montant_total') current_sale.save() return redirect('products-list') context = {'sale': current_sale, 'list_user': list_user, 'list_product': list_product} return render(request, 'daara/add_sale.html', context)
模板文件add_sale.html
<div class="card-body"> <form method="POST"> {% csrf_token %} <div class="form-group col-md-6"> <label for="utilisateur">Utilisateur</label> <select class="form-control" name="user"> <option value="1" selected="selected">Selectionez un utilisateur</option> {% for user in list_user %} {% if user.id == sale.user.id %} <option value="{{sale.user.id}}" selected="selected">{{sale.user.username}}</option> {% else %} <option value="{{user.id}}">{{user.username}}</option> {% endif %} {% endfor %} </select> </div> <div class="form-group col-md-6"> <label for="produit">Produit</label> <select class="form-control" name="product" id="product"> <option value="0" selected="selected">Selectionez un produit</option> {% for product in list_product %} {% if product.id == sale.product.id %} <option value="{{sale.product.id}}" selected="selected">{{sale.product.name}}</option> {% else %} <option value="{{product.id}}">{{product.name}}</option> {% endif %} {% endfor %} </select> </div> <div class="form-group col-md-6"> <label for="quantity">Quantity</label> <input type="number" class="form-control" id="qte" name="quantity" value="{{sale.quantity}}"> </div> <div class="form-group col-md-6"> <label for="sale_price">Price</label><input type="number" step="0.01" class="form-control" id="product_price" name="sale_price" value="{{product.price}}"> </div> <div class="form-group col-md-6" id="#montant"> <label for="montant">Montant Total</label> <input type="number" step="0.01" class="form-control" id="montant" name="montant_total" value="{{sale.montant_total}}"> </div> <div class="text-end"> <a class="btn btn-secondary" href="{% url 'products-list' %}" type="button">Close</a> <button class="btn btn-success" type="submit" value="save">Save</button> </div> </form> <p>{{product_id}}aaa</p> </div>
URL配置
path('ad-sale', views.addSale, name="ad-sale")
问题修正与实现方案
1. 模型字段优化
原模型中sale_price用PositiveIntegerField无法存储小数价格,montant_total用CharField不适合存储金额,修改为:
class Sale(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, null=True) product = models.ForeignKey('Product', on_delete=models.CASCADE) quantity = models.PositiveIntegerField(default=1) sale_price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) montant_total = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) def __str__(self): return f"{self.product.name} - {self.montant_total}" def save(self, *args, **kwargs): # 自动计算总金额,无需手动输入 self.montant_total = self.sale_price * self.quantity super().save(*args, **kwargs)
2. 视图逻辑修正
修复POST请求中获取价格的错误,新增自动从产品对象取价格的逻辑:
def addSale(request=None): current_sale = Sale() list_user = User.objects.all().order_by('-username') list_product = Product.objects.all().order_by('-name') if request.POST: # 处理用户选择 user_id = request.POST.get('user') if user_id and user_id != "1": current_sale.user = User.objects.get(id=user_id) # 处理产品选择,自动填充价格 product_id = request.POST.get('product') if product_id and product_id != "0": product = Product.objects.get(id=product_id) current_sale.product = product current_sale.sale_price = product.price # 处理数量 quantity = request.POST.get('quantity') if quantity: current_sale.quantity = int(quantity) # 总金额自动计算,无需赋值 current_sale.save() return redirect('products-list') context = {'sale': current_sale, 'list_user': list_user, 'list_product': list_product} return render(request, 'daara/add_sale.html', context)
3. 模板与前端交互实现
修改模板,添加产品价格的data属性,用JS监听选择事件自动填充价格和计算总金额:
<div class="card-body"> <form method="POST"> {% csrf_token %} <div class="form-group col-md-6"> <label for="utilisateur">Utilisateur</label> <select class="form-control" name="user"> <option value="1" {% if not sale.user %}selected{% endif %}>Selectionez un utilisateur</option> {% for user in list_user %} <option value="{{user.id}}" {% if user.id == sale.user.id %}selected{% endif %}>{{user.username}}</option> {% endfor %} </select> </div> <div class="form-group col-md-6"> <label for="produit">Produit</label> <select class="form-control" name="product" id="product"> <option value="0" {% if not sale.product %}selected{% endif %}>Selectionez un produit</option> {% for product in list_product %} <option value="{{product.id}}" data-price="{{product.price}}" {% if product.id == sale.product.id %}selected{% endif %}>{{product.name}}</option> {% endfor %} </select> </div> <div class="form-group col-md-6"> <label for="quantity">Quantity</label> <input type="number" class="form-control" id="qte" name="quantity" value="{{sale.quantity}}"> </div> <div class="form-group col-md-6"> <label for="sale_price">Price</label> <input type="number" step="0.01" class="form-control" id="product_price" name="sale_price" value="{{sale.sale_price}}"> </div> <div class="form-group col-md-6" id="montant"> <label for="montant">Montant Total</label> <input type="number" step="0.01" class="form-control" id="montant_total" name="montant_total" value="{{sale.montant_total}}" readonly> </div> <div class="text-end"> <a class="btn btn-secondary" href="{% url 'products-list' %}" type="button">Close</a> <button class="btn btn-success" type="submit" value="save">Save</button> </div> </form> <p>{{product_id}}aaa</p> </div> <script> // 产品选择事件:自动填充价格 document.getElementById('product').addEventListener('change', function() { const selectedOption = this.options[this.selectedIndex]; const price = selectedOption.getAttribute('data-price'); if (price) { document.getElementById('product_price').value = price; calculateTotal(); } else { document.getElementById('product_price').value = '0.00'; document.getElementById('montant_total').value = '0.00'; } }); // 数量/价格变化时自动计算总金额 document.getElementById('qte').addEventListener('input', calculateTotal); document.getElementById('product_price').addEventListener('input', calculateTotal); function calculateTotal() { const quantity = parseFloat(document.getElementById('qte').value) || 0; const price = parseFloat(document.getElementById('product_price').value) || 0; const total = (quantity * price).toFixed(2); document.getElementById('montant_total').value = total; } // 页面加载时初始化总金额 window.addEventListener('load', calculateTotal); </script>
4. URL配置保持不变
path('ad-sale', views.addSale, name="ad-sale")
内容的提问来源于stack exchange,提问作者Daara Bah
相关产品推荐
相关产品推荐

