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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:37:03