Как загрузить цену продажи на основе селектора с помощью django

hi Я новичок в 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:

url:

path('ad-sale', views.addSale, name="ad-sale")

Я застрял и не могу разблокировать, пожалуйста, мне нужна ваша помощь

Примечание: аргументы запроса являются строками.

На ваших моделях вы определили quantity и sale_price как IntegerFields.

class Sale(models.Model):
...
  quantity = models.PositiveIntegerField(default=1)
  sale_price = models.PositiveIntegerField(default=0)

Но на ваш взгляд, вы не преобразуете строковые аргументы в целые числа при сохранении экземпляра Sale модели.

Измените свой код на следующий:

def addSale(request=None):
    ...

    if request.POST:
       ...
        if request.POST.get('quantity') != "":
            current_sale.quantity = int(request.POST.get('quantity'))
        if request.POST.get('sale_price') != "":
            current_sale.sale_price = int(request.GET.get('price'))
        ...
        current_sale.save()
        return redirect('products-list')
     ...

Совет:

Гораздо лучше использовать Django Forms для обработки пользовательского ввода, а не извлекать каждый аргумент вручную, как это делаете вы. ссылка на Forms

Вы имеете в виду, что каждый продукт имеет заранее определенную цену, и вы хотите, чтобы эта цена отображалась при выборе соответствующего продукта?

Если да, то быстрым решением будет отображение цены непосредственно на опции выбора, что НЕ требует никакого JavaScript.

Предположим, что ваша Product модель определена как такая. Чтобы этот ответ сработал, необходимо изменить ее метод __str__.

class Product(models.Model):
    name = models.CharField(max_length=xxx)
    # According to your template, sale_price have 2 decimal 
    # places, conflict with your Sale model definition. 
    # Thus I change field type to DecimalField. 
    sale_price = models.DecimalField(max_digits=12, decimal_places=2)
    # ... other fields
    def __str__(self):
        # django form calls this method when rendering ForeignKey options
        return f'{self.name} {self.sale_price}'

Как посоветовал @Hujaakbar, встроенный ModelForm является рекомендуемым способом проверки данных. А ваше представление можно переписать следующим образом

from django.forms import modelform_factory

def addSale(request):
    SaleForm = modelform_factory(Sale, fields='__all__')
    if request.method == 'POST':
        form = SaleForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('product-list')
    else:
        form = SaleForm()
    context = {'form': form}
    return render(request, 'daara/add_sale.html', context)

И ваш шаблон

<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">
                {% for option in form.user.subwidgets %}
                    {{ option }}
                {% endfor %}
            </select>
        </div>
                           
        <div class="form-group col-md-6">
            <label for="produit">Produit</label>
            <select class="form-control" name="product" id="product">
                 {% for option in form.product.subwidgets %}
                     {{ 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="{{form.quantity.value}}">
        </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="{{form.product.value}}">
        </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="{{form.montant_total.value}}">
        </div>


        <div class="text-end">
            {# anchor tag does not support type="button" #}
            <a class="btn btn-secondary" href="{% url 'products-list' %}" type="button">Close</a>
            {# value="save" attribute has no effect here #}
            <button class="btn btn-success" type="submit" value="save">Save</button>
        </div>
    </form>
    {# The context has no product_id attribute #}
    <p>{{product_id}}aaa</p>

</div>

Дополнительное мнение:

  1. если Sale.sale_price всегда совпадает с Product.sale_price, то Sale.sale_price не нужен и может быть удален;
  2. если montant_total просто sale_price * quantity, то он также не нужен и может быть удален;
Вернуться на верх