首页 > 解决方案 > 如何将 django formset 与自定义模板一起使用?

问题描述

Inlineformset在我的django项目中使用过,但是我必须使用我自己的js来增加表格!但我没有找到任何方法让它工作

这是我的models.py

class Invoice(models.Model):
    seller = models.ForeignKey(User,on_delete=models.CASCADE)
    customer = models.CharField(max_length=50)
    items = models.ManyToManyField(Item,through='InvoiceItem')

class InvoiceItem(models.Model):
    item = models.ForeignKey(Item,on_delete=models.CASCADE)
    invoice = models.ForeignKey(CustomerInvoice,on_delete=models.CASCADE,related_name='invoice')
    quantity = models.IntegerField()
    price = models.DecimalField(max_digits=20,decimal_places=3)
    cash = models.DecimalField(max_digits=20,decimal_places=3)
    discount = models.DecimalField(max_digits=20,decimal_places=3)

这段代码是我的views.py,我使用了基于类的视图

class CreateClientInvoiceView(LoginRequiredMixin,SuccessMessageMixin,CreateView):
    model = CustomerInvoice
    form_class = ClientInvoiceForm
    template_name = 'invoiceapp/create_invoice.html'
def get_context_data(self,*args,**kwargs):
    data = super().get_context_data(*args,**kwargs)
    if self.request.POST:
        data['items'] = CustomerInvoiceInlineFormset(self.request.POST)
        data['items'].full_clean()
    else:
        data['items'] = CustomerInvoiceInlineFormset()
    return data

def form_valid(self, form):
    res = super().form_valid(form)
    self.object = form.save()
    context = self.get_context_data()
    items = context['items']
    with transaction.atomic:
        form.instance.seller = self.request.user
        if form.is_valid() and items.is_valid() and items.cleaned_data !={}:
            items.instance = self.object
            items.save()
            form.save()
        else:
            return render(self.request,self.template_name,context)
    return super().form_valid(form)

def get_success_url(self):
    return reverse_lazy('invoiceapp:customer-invoice',kwargs={'pk':self.object.pk})

这是我的 html + js 代码

{% extends 'base.html' %}
{% load widget_tweaks %}
{% load static %}
{% block title %}
create new invoice
{% endblock %}

{% block content %}

<form method="POST">{% csrf_token %}
    {{items.management_form}}
      <div class="w-full  md:w-11/12 mx-auto realative p-2 bg-gray-200 invoice" style="direction: ltr !important;">

        <div class="p-1 pr-2 pb-1 text-xs border border-black rounded-lg flex flex-wrap">

            <div class="flex w-8/12 lg:w-9/12">
              
                <div class="w-10/12 ml-8 border-b border-gray-600 border-dotted">

                    {{form.customer | add_class:'bg-transparent w-full text-right focus:outline-none'}}
                </div>  
                <div class="">
                  :  ناو
                </div>
            </div>
        </div>
        <!-- table -->
        <div class="mt-1 border border-black">
            <!-- header -->
            <div class="flex flex-wrap grayBG text-sm text-white">
                <div class="w-1/12 text-center border-r">
                    <i class="fas fa-cog"></i>
                </div>
                <div class="w-2/12  border-r text-center">
                    total price 
                </div>
                <div class="w-2/12  border-r text-center">
                    discount
                </div>
                <div class="w-1/12  border-r text-center">
                    cash
                </div>
                <div class="w-1/12  border-r text-center">
                    loan
                </div>
                <div class="w-1/12  border-r text-center">
                    price
                </div>
                <div class="w-2/12  border-r text-center">
                    quantity
                </div>
                <div class="w-2/12  border-r text-center">
                    product
                </div>
            
            </div>
            <!-- inputs -->
            <div id="allInp">
                <div class="flex flex-wrap grayBG text-sm text-black inp">
                    <div class="w-1/12 border-r">

                    </div>
                    <div class="w-2/12 p-2 border-r text-center">
                      <input type="number" class="totalSumField rounded-lg focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-2/12 p-2 border-r text-center">
                      <input type="text" onkeyup="totalSum()" class="rounded-lg discount focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
                        <input type="number" onkeyup="totalSum()"  class="rounded-lg cash focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
                        <input type="number" onkeyup="totalSum()"  class="rounded-lg loan focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
                        <input type="number" onkeyup="totalSum()"  class="rounded-lg price focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-2/12 p-2 border-r text-center ">
                        <input type="number" onkeyup="totalSum()"  class="rounded-lg quantity focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-2/12 p-2 border-r text-center">
                        <datalist id="jor">
                            <option value="test">
                            <option value="test">
                            <option value="test">
                            <option value="test">
                            <option value="test">
                          </datalist>
                        <input type="text" list="jor" class="w-full rounded-lg focus:outline-none py-1">
                    
                    </div>
                
                </div>
            </div>
            <div class="flex flex-wrap grayBG justify-between text-sm mt-2 text-black">
                <button class=" grayBG border border-white focus:outline-none text-white m-2 rounded-lg py-1 px-4  text-sm" id="addRow">
                    add new row <i class="fas fa-plus"></i>
                </button>

                <div class="w-6/12 flex">
                    <div class="w-6/12 p-2 border-r text-center">
                        <p class="mb-2 text-white">total invoice price </p>
                        <input type="number" id="total" class="rounded-lg focus:outline-none py-1 w-full text-center" placeholder="total invoice price">
                    </div>
                    <div class="w-6/12 p-2 border-r text-center">
                        <p class="mb-2 text-white">total loan</p>
                        <input type="number" id="loan" class="rounded-lg  focus:outline-none py-1 w-full text-center" placeholder="loan">
                    </div>
                </div>

            </div>
            
            <!-- clone -->
            <div  class="hidden">
                <div class="inp flex flex-wrap grayBG text-sm text-black" id="inputs">
                    <div class="w-1/12 border-r flex flex-wrap justify-center items-center">
                        <button id="removeRow" class="bg-white rounded-lg text-red-500 px-3">
                            <i class="fas fa-trash"></i>
                        </button>
                    </div>
                    <div class="w-2/12 p-2 border-r text-center">
                      <input type="text" class="rounded-lg totalSumField focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-2/12 p-2 border-r text-center">
                      <input type="text" onkeyup="totalSum()" class="rounded-lg focus:outline-none discount py-1 w-full">
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
                        <input type="number" onkeyup="totalSum()"  class="rounded-lg cash focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
                        <input type="number" onkeyup="totalSum()"  class="rounded-lg loan focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
                        <input type="number" onkeyup="totalSum()"  class="rounded-lg price focus:outline-none py-1 w-full">
                    </div>

                    <div class="w-2/12 p-2 border-r text-center ">
                        <input type="number" onkeyup="totalSum()" class="rounded-lg quantity focus:outline-none py-1 w-full">
                    </div>
                    
                
                    <div class="w-2/12 p-2 border-r text-center">
                        <datalist id="jor">
                            <option value="test">
                            <option value="test">
                            <option value="test">
                            <option value="test">
                            <option value="test">
                          </datalist>
                        <input type="text" list="jor" class="w-full rounded-lg focus:outline-none py-1">
                    
                    </div>
                
                </div>
            </div>

          
          
        </div>
        
    </div>

    <div class="w-6/12 text-center mt-1 mx-auto mb-6">
        <button type="submit" class= w-full bg-white text-gray-900" id="print">print</button>
    </div>
</form>
   

    </div>
  </div>

</body>

</html>



<script>
  
  $('#print').click(function(){
  $('.invoice').printThis();
})

$("#addRow").click(function () {
    totalSum();
    var html = $("#inputs").clone();
    $('#allInp').append(html);
  });


  $(document).on('click', '#removeRow', function () {
      $(this).closest('#inputs').remove();
      totalSum();
  });

  function counting(result) { 
      document.getElementById("total").value= result;
      
   }

  function countingloan(result) { 
      document.getElementById("loan").value= result;
      
   }

   counting(0);
   countingloan(0);

   function totalSumField () {
    let inp = document.querySelectorAll("#allInp > .inp");
    let result=0;
      for(let i=0;i<inp.length;i++){
         let price=inp[i].getElementsByClassName("price")[0].value;
         let quantity=inp[i].getElementsByClassName("quantity")[0].value;
         let cash=inp[i].getElementsByClassName("cash")[0].value;
         let discount=inp[i].getElementsByClassName("discount")[0].value;
         inp[i].getElementsByClassName("totalSumField")[0].value=(price*quantity)-discount;
         inp[i].getElementsByClassName("loan")[0].value=((price*quantity)-discount)-cash;
      } 
      
   
  }




  function totalSum () {
    let inp = document.querySelectorAll("#allInp > .inp");
    let result=0;
    let loan=0;
      for(let i=0;i<inp.length;i++){
         let price=inp[i].getElementsByClassName("price")[0].value;
         let quantity=inp[i].getElementsByClassName("quantity")[0].value;
         let cash=inp[i].getElementsByClassName("cash")[0].value;
         let discount=inp[i].getElementsByClassName("discount")[0].value;

         result+=(price*quantity)-discount;
         loan+=((price*quantity)-discount)-cash;
      } 
      countingloan(loan);
      counting(result)
      totalSumField()
  }


  
</script>
{% endblock %}

问题出在这里我想制作自己的html和js而不是使用jquery.formset.js,因为当有人写价格和数量时我必须这样做,然后它会自动将它们相乘并将总价格写在一个字段中,现在我想知道如何添加输入字段以获得我期望的结果?这仅适用于第一种形式

            <div id="allInp">
                {% for item in items.forms %}
                {{item.id}}
                <div class="flex flex-wrap grayBG text-sm text-black inp">
                    <div class="w-1/12 border-r">
                    </div>
                    <div class="w-2/12 p-2 border-r text-center">
                      <input type="number" class="totalSumField rounded-lg focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-2/12 p-2 border-r text-center">
                        {{item.discount | add_class:'rounded-lg discount focus:outline-none py-1 w-full'}}
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
                        {{item.cash|add_class:'rounded-lg cash focus:outline-none py-1 w-full'}}
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
           
                        <input type="number" onkeyup="totalSum()"  class="rounded-lg qarz focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
                        {{item.price | add_class:'rounded-lg price  focus:outline-none py-1 w-full'}}
                    </div>
                    <div class="w-2/12 p-2 border-r text-center ">
                        {{item.quantity | add_class:'rounded-lg quantity focus:outline-none py-1 w-full'}}
                    </div>
                    <div class="w-2/12 p-2 border-r text-center">
                        {{item.item|add_class:'w-full rounded-lg focus:outline-none py-1'}}
                    
                    </div>
                
                </div>
                {% endfor %}
            </div>
            
            
            <div  class="hidden">
                <div class="inp flex flex-wrap grayBG text-sm text-black" id="inputs">
                    <div class="w-1/12 border-r flex flex-wrap justify-center items-center">
                        <button id="removeRow" class="bg-white rounded-lg text-red-500 px-3">
                            <i class="fas fa-trash"></i>
                        </button>
                    </div>
                    <div class="w-2/12 p-2 border-r text-center">
                      <input type="text" class="rounded-lg totalSumField focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-2/12 p-2 border-r text-center">
                        {{item.discount | add_class:'rounded-lg discount focus:outline-none py-1 w-full'}}
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
                        {{item.cash|add_class:'rounded-lg cash focus:outline-none py-1 w-full'}}
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
                        <input type="number" onkeyup="totalSum()"  class="rounded-lg qarz focus:outline-none py-1 w-full">
                    </div>
                    <div class="w-1/12 p-2 border-r text-center ">
                        {{item.price | add_class:'rounded-lg price focus:outline-none py-1 w-full'}}
                    </div>

                    <div class="w-2/12 p-2 border-r text-center ">
                        {{item.quantity | add_class:'rounded-lg quantity focus:outline-none py-1 w-full'}}
                    </div>
                    
                
                    <div class="w-2/12 p-2 border-r text-center">
                        {{item.item|add_class:'w-full rounded-lg focus:outline-none py-1'}}
                    </div>
                
                </div>
            </div>
            

我非常感谢您的帮助,请尽可能让我知道最问候..

标签: javascriptpythonjquerydjango

解决方案


推荐阅读