Django & Js:在简单的 HTML 输入上使用 cleaned_data 而不是 request.POST
Django & Js : use cleaned_data instead of request.POST on simple HTML inputs
我在 forms.py 中创建了一个表单,提交表单后,使用 form.cleaned_data
将值顺利插入到我的数据库中。
我的模板有一个按钮(称为:"ajouter une ligne"),用于添加一个新行(该行包含与原始表格相似的表格)。此操作(添加行)由 Js 编码。
我的问题是,当我想提交包含原始行和第二行的最终表格时。它只提交第一个,因为第一个 ligne 是在 forms.py 上创建的,所以在提交时它是用 clean_data 提交的。然而,第二行是直接使用 js 在模板上创建的,因此 form.cleaned_data
不起作用。
这是我的模板原始行:
<form action="/veentes" method="POST" enctype="multipart/form-data">{%
csrf_token %}{{ form.non_field_errors }}
<table style ="border-collapse: separate;border-spacing: 15px;" id="div1">
<tr><td width="5%">N P</td><td width="25%">Désignation</td><td width="8%">Date de Facture</td><td width="10%">Montant HT</td><td width="10%">TVA</td><td width="10%">Montant TTC</td></tr>
<tr style="border:1px solid black;" >
<td><div class="col-xs-1"><b><p name="np1">1</p></b></div></td>
<td>
{% render_field form.designation1 class="form-control" id="inlineFormInputName" placeholder="désignation" name="designation1" %}{{form.degn.errors}}
</td>
<td>{% render_field form.datefacture1 class="form-control" id="inlineFormInputName" placeholder="Date de Facture" name="datefacture1" %}{{form.dateFac.errors}}
</td>
<td>
{% render_field form.mht1 class="form-control" id="inlineFormInputName" placeholder="Montant HT" name="mht1" %}{{form.mht.errors}}
</td>
<td>
{% render_field form.mtva1 class="form-control" id="inlineFormInputName" placeholder="TVA" name="mtva1" %}{{form.mtva.errors}}
</td>
<td>{% render_field form.mttc1 class="form-control"
id="inlineFormInputName" placeholder="Montant TTC" name="mttc1" %}
{{form.mttc.errors}}
</td>
</form>
</tr>
这是我创建新行的 Js 代码:
var click=1;
function addform() {
click +=1;
var element = document.getElementById("div1");
//create a tr
var id_tr="tr"+click;
create_tr(element, id_tr);
document.getElementById('num').value=click;
//create inputs
var designation = document.createElement("INPUT");
textinput(designation, "text" , "designation", "form-control",
"Désignation",click);
var datef = document.createElement("INPUT");
textinput(datef, "date" , "datefacture", "form-control", "Date de
Facture",click);
var mht = document.createElement("INPUT");
textinput(mht, "text" , "mht", "form-control", "Montant HT",click);
var mtva = document.createElement("INPUT");
textinput(mtva, "text" , "mtva", "form-control", "Montant TVA",click);
var mttc = document.createElement("INPUT");
textinput(mttc, "text" , "mttc", "form-control", "Montant TTC",click);
var elmtr=document.getElementById(id_tr);
var y = document.createElement("TD");
var td="td";
td=td + id_tr;
y.setAttribute("id", td+0);
elmtr.appendChild(y);
var elmtd=document.getElementById(td+0);
var x = document.createElement("B");
x.setAttribute("name","np"+click);
x.setAttribute("class","col-xs-1");
var t = document.createTextNode(click);
x.appendChild(t);
elmtd.appendChild(x);
create_tds(elmtr, designation, 1 ,id_tr);
create_tds(elmtr, datef, 2 ,id_tr);
create_tds(elmtr, mht, 4 ,id_tr);
create_tds(elmtr, mtva, 5,id_tr);
create_tds(elmtr, mttc, 6 , id_tr);
}
function create_tr(element, id_tr){
var trr = document.createElement("TR");
trr.setAttribute("id", id_tr);
element.appendChild(trr);
}
function create_tds(elmtr,input_td, clicktd,id_tr){
var y = document.createElement("TD");
var td="td";
td=td + id_tr;
y.setAttribute("id", td+clicktd);
elmtr.appendChild(y);
var elmtd=document.getElementById(td+clicktd);
elmtd.appendChild(input_td);
}
function textinput(x, type, name, classe, placeholder,click){
x.setAttribute("type", type);
x.setAttribute("name", name+click);
x.setAttribute("class", classe);
x.setAttribute("placeholder", placeholder);
if (name=="file") {
x.setAttribute("disabled", "disabled");
}
if (type == "button") {
x.setAttribute("value", "importer");
}
}
我的观点代码是:
def post(self,request,*args,**kwargs):
if request.method == "POST":
p=int(request.POST['numpiece'])
print(p)
np=p
form=FormVents(request.POST,request.FILES)
#np=1
print("numpiece")
np=2
x=client.objects.all().filter(nom=request.POST['client_name']).values_list('id', flat=True)
if form.is_valid():
for j in range(1,np+1):
print(j)
vent=ventes(numpiece=j,id_facture_id=v.id,designation=form.cleaned_data.get('designation'+str(j)),montantHT=form.cleaned_data.get('mht'+str(j)),montantTVA=form.cleaned_data.get('mtva'+str(j)),montantTTC=form.cleaned_data.get('mttc'+str(j)))
vent.save()
else:
form = forms.FormVents(request.POST or None)
form.py :
class FormVents(forms.Form):
designation1=forms.CharField()
datefacture1=forms.DateField(initial=datetime.date.today)
mht1=forms.FloatField()
mtva1=forms.FloatField()
mttc1=forms.FloatField()
请给我任何想法,我怎样才能在我的第二行也使用 cleaned_data
?
PS:当我用 request.POST
替换 form.cleaned_data
时,它添加了两行,但我想使用 cleaned_data 添加我的所有行,因为我读到为了数据安全我需要工作form.cleaned_data。
所以请帮我解决这个问题。非常感谢
看看 Django 中的 Formsets。它们允许批量提交多个对象。您可以根据现有表格创建它:
class FormVents(forms.Form):
designation1=forms.CharField()
datefacture1=forms.DateField(initial=datetime.date.today)
mht1=forms.FloatField()
mtva1=forms.FloatField()
mttc1=forms.FloatField()
VentsFormSet = formset_factory(FormVents)
然后,在您看来,您几乎可以像正常形式一样使用它。唯一的区别是您需要遍历您的表单集来为每个对象提取数据:
formset = VentsFormSet(request.POST, request.FILES)
if formset.is_valid():
for form in formset:
data_to_be_saved = form.cleaned_data
我在 forms.py 中创建了一个表单,提交表单后,使用 form.cleaned_data
将值顺利插入到我的数据库中。
form.cleaned_data
不起作用。
这是我的模板原始行:
<form action="/veentes" method="POST" enctype="multipart/form-data">{%
csrf_token %}{{ form.non_field_errors }}
<table style ="border-collapse: separate;border-spacing: 15px;" id="div1">
<tr><td width="5%">N P</td><td width="25%">Désignation</td><td width="8%">Date de Facture</td><td width="10%">Montant HT</td><td width="10%">TVA</td><td width="10%">Montant TTC</td></tr>
<tr style="border:1px solid black;" >
<td><div class="col-xs-1"><b><p name="np1">1</p></b></div></td>
<td>
{% render_field form.designation1 class="form-control" id="inlineFormInputName" placeholder="désignation" name="designation1" %}{{form.degn.errors}}
</td>
<td>{% render_field form.datefacture1 class="form-control" id="inlineFormInputName" placeholder="Date de Facture" name="datefacture1" %}{{form.dateFac.errors}}
</td>
<td>
{% render_field form.mht1 class="form-control" id="inlineFormInputName" placeholder="Montant HT" name="mht1" %}{{form.mht.errors}}
</td>
<td>
{% render_field form.mtva1 class="form-control" id="inlineFormInputName" placeholder="TVA" name="mtva1" %}{{form.mtva.errors}}
</td>
<td>{% render_field form.mttc1 class="form-control"
id="inlineFormInputName" placeholder="Montant TTC" name="mttc1" %}
{{form.mttc.errors}}
</td>
</form>
</tr>
这是我创建新行的 Js 代码:
var click=1;
function addform() {
click +=1;
var element = document.getElementById("div1");
//create a tr
var id_tr="tr"+click;
create_tr(element, id_tr);
document.getElementById('num').value=click;
//create inputs
var designation = document.createElement("INPUT");
textinput(designation, "text" , "designation", "form-control",
"Désignation",click);
var datef = document.createElement("INPUT");
textinput(datef, "date" , "datefacture", "form-control", "Date de
Facture",click);
var mht = document.createElement("INPUT");
textinput(mht, "text" , "mht", "form-control", "Montant HT",click);
var mtva = document.createElement("INPUT");
textinput(mtva, "text" , "mtva", "form-control", "Montant TVA",click);
var mttc = document.createElement("INPUT");
textinput(mttc, "text" , "mttc", "form-control", "Montant TTC",click);
var elmtr=document.getElementById(id_tr);
var y = document.createElement("TD");
var td="td";
td=td + id_tr;
y.setAttribute("id", td+0);
elmtr.appendChild(y);
var elmtd=document.getElementById(td+0);
var x = document.createElement("B");
x.setAttribute("name","np"+click);
x.setAttribute("class","col-xs-1");
var t = document.createTextNode(click);
x.appendChild(t);
elmtd.appendChild(x);
create_tds(elmtr, designation, 1 ,id_tr);
create_tds(elmtr, datef, 2 ,id_tr);
create_tds(elmtr, mht, 4 ,id_tr);
create_tds(elmtr, mtva, 5,id_tr);
create_tds(elmtr, mttc, 6 , id_tr);
}
function create_tr(element, id_tr){
var trr = document.createElement("TR");
trr.setAttribute("id", id_tr);
element.appendChild(trr);
}
function create_tds(elmtr,input_td, clicktd,id_tr){
var y = document.createElement("TD");
var td="td";
td=td + id_tr;
y.setAttribute("id", td+clicktd);
elmtr.appendChild(y);
var elmtd=document.getElementById(td+clicktd);
elmtd.appendChild(input_td);
}
function textinput(x, type, name, classe, placeholder,click){
x.setAttribute("type", type);
x.setAttribute("name", name+click);
x.setAttribute("class", classe);
x.setAttribute("placeholder", placeholder);
if (name=="file") {
x.setAttribute("disabled", "disabled");
}
if (type == "button") {
x.setAttribute("value", "importer");
}
}
我的观点代码是:
def post(self,request,*args,**kwargs):
if request.method == "POST":
p=int(request.POST['numpiece'])
print(p)
np=p
form=FormVents(request.POST,request.FILES)
#np=1
print("numpiece")
np=2
x=client.objects.all().filter(nom=request.POST['client_name']).values_list('id', flat=True)
if form.is_valid():
for j in range(1,np+1):
print(j)
vent=ventes(numpiece=j,id_facture_id=v.id,designation=form.cleaned_data.get('designation'+str(j)),montantHT=form.cleaned_data.get('mht'+str(j)),montantTVA=form.cleaned_data.get('mtva'+str(j)),montantTTC=form.cleaned_data.get('mttc'+str(j)))
vent.save()
else:
form = forms.FormVents(request.POST or None)
form.py :
class FormVents(forms.Form):
designation1=forms.CharField()
datefacture1=forms.DateField(initial=datetime.date.today)
mht1=forms.FloatField()
mtva1=forms.FloatField()
mttc1=forms.FloatField()
请给我任何想法,我怎样才能在我的第二行也使用 cleaned_data
?
PS:当我用 request.POST
替换 form.cleaned_data
时,它添加了两行,但我想使用 cleaned_data 添加我的所有行,因为我读到为了数据安全我需要工作form.cleaned_data。
所以请帮我解决这个问题。非常感谢
看看 Django 中的 Formsets。它们允许批量提交多个对象。您可以根据现有表格创建它:
class FormVents(forms.Form):
designation1=forms.CharField()
datefacture1=forms.DateField(initial=datetime.date.today)
mht1=forms.FloatField()
mtva1=forms.FloatField()
mttc1=forms.FloatField()
VentsFormSet = formset_factory(FormVents)
然后,在您看来,您几乎可以像正常形式一样使用它。唯一的区别是您需要遍历您的表单集来为每个对象提取数据:
formset = VentsFormSet(request.POST, request.FILES)
if formset.is_valid():
for form in formset:
data_to_be_saved = form.cleaned_data