javascript - 如何将 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>
我非常感谢您的帮助,请尽可能让我知道最问候..
解决方案
推荐阅读
- google-sheets - 结束时间戳跨到午夜的 2 个时间戳之间的 Google 表格持续时间
- axios - Axios 发送带有参数的 url 作为字符串而不是对象
- mongodb - $elemMatch 相当于嵌套数组 com.mongodb.client.model.Filters.elemMatch
- javascript - 将 React Context API 类转换为 Hook 的函数
- javascript - React-native UI 未使用第一个 onPress() 触发器更新
- javascript - 在 Cypress 中使用 env 变量覆盖配置文件
- arrays - 为什么我不能对从后端返回的数组使用数组方法
- python - Python - Azure SQL 慢速插入与本地数据库
- camunda - 返回上一个任务时文件变量设置为空
- laravel - 我正在尝试显示单个数据,但它显示“尝试获取非对象的属性 'id'”