我有一个 Django 项目,其中包含两个表单,我想通过两个单独的 ajax 请求提交这两个表单。第一个 ajax 请求实际上应该填写第二个表单的一个值,该值已成功完成。此外,第二个表单有一些初始值,我稍后计划将其隐藏,以便用户在提交第一个表单后只能看到需要填写的必要字段。
在我的视图中检查“
ajax_type
”和“request.is_ajax()
”后,我传入“request.method == 'POST
”关键字以确定ajax类型是第一个ajax请求还是第二个。我的第二个ajax请求使使用模型表单,该表单应该在验证后创建模型的新实例。
我的看法:
def canadaTaxEntries(request):
newest_record = LAWCHG.objects.aggregate(Max('control_number'))
newest_control_number = newest_record["control_number__max"]
print(newest_control_number)
today = date.today().strftime("1%y%m%d")
current_time = time.strftime("%H%M%S")
#print(today)
#print(current_time)
initial_data = {
'control_number': (newest_control_number + 1),
'item_number': None,
'vendor_tax_code': None,
'expiration_flag': 1,
'charge_category': None,
'charge_desc_code': None,
'country': 'US',
'state': None,
'city': None,
'county': None,
'charge_amount': None,
'charge_uom': 'CA',
'charge_percentage': 0.0,
'apply_flag': 1,
'beg_del_date': None,
'end_del_date': None,
'rev_date': today,
'rev_time': current_time,
'est_date': today,
'est_time': current_time,
'program_id': 'BI008',
'operator_id': 'FKRUGER',
}
canada_tax_form = CanadaTaxForm(request.POST or None, initial=initial_data)
if request.is_ajax():
if request.method == 'POST':
canada_tax_form = CanadaTaxForm(request.POST or None, initial=initial_data)
data = json.load(request)
#item_number = request.POST.get('itm', False)
ajax_type = data.get("ajax_type")
if ajax_type == "screen_item":
print('1st request')
num = data.get("item")
itmnum = int(num)
return screen_item_ajax(itmnum)
elif ajax_type == "tax_entry":
print("2nd request")
if canada_tax_form.is_valid():
print("VALID")
canada_tax_form.save()
else:
print("NOT VALID")
print(canada_tax_form.errors)
controlnum = data.get("control_num")
itemnum = data.get("item")
ventaxnum = data.get("vend_tax")
return canada_tax_entries_ajax(request, controlnum, itemnum, ventaxnum)
context = {
"canada_tax_form":canada_tax_form,
}
return render(request, "html/canadaTaxEntries.html", context)
我的ajax请求:
$(document).on('submit', '#item_num_form', function (e) {
let item_number = document.getElementById("item_number").value
console.log(item_number)
e.preventDefault()
$.ajax({
url: "http://127.0.0.1:8000/canada/",
type: 'POST',
dataType: "json",
data: JSON.stringify({
ajax_type: "screen_item",
item: item_number,
}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
success: function (data) {
console.log(data)
console.log("AJAX Worked!")
let description = data.item_info[0].item_description;
document.getElementById("description").innerHTML = "Item Description: " + description;
let upc_num = data.item_info[0].upc_14_long;
document.getElementById("upc_num").innerHTML = " UPC Number: " + upc_num;
document.getElementById("id_item_number").value = item_number;
function getTH() {
const column = table_headers;
const head = document.querySelector('thead');
let tags = "<tr>";
for (i = 0; i < column.length; i++){
tags += `<th>${column[i]}</th>`;
}
tags += "</tr>"
head.innerHTML = tags;
getTD();
}
function getTD() {
const body = document.querySelector('tbody');
let tags = "";
data.existing_tax_records.map(d => {
tags += `<tr>
<td>${d.beg_del_date}</td>
<td>${d.end_del_date}</td>
<td>${d.charge_amount}</td>
<td>${d.charge_uom}</td>
<td>${d.apply_flag}</td>
<td>${d.charge_category_id}</td>
<td>${d.charge_desc_code_id}</td>
<td>${d.vendor_tax_code}</td>
<td>${d.control_number}</td>
</tr>`
})
body.innerHTML = tags;
}
getTH()
}
})
})
$(document).on('submit', '#tax_form', function (e) {
let control_number = document.getElementById("id_control_number").value
let item_number = document.getElementById("id_item_number").value
let vendor_tax_code = document.getElementById("id_vendor_tax_code").value
console.log(control_number)
e.preventDefault()
$.ajax({
url: "http://127.0.0.1:8000/canada/",
type: 'POST',
dataType: "json",
data: JSON.stringify({
ajax_type: "tax_entry",
control_num: control_number,
item: item_number,
vend_tax: vendor_tax_code,
}),
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": getCookie("csrftoken"),
},
success: function (data) {
console.log(data)
console.log("2nd AJAX Worked!")
console.log("Is form valid???")
},
error: function (error) {
console.log(error)
console.log("2nd AJAX Failed")
}
})
})
我的两个 ajax 请求都返回成功消息,因此触发了提交第二个表单的触发器。我认为问题与我的表单在提交之前被擦除有关,即使我在点击第二个表单的提交按钮时填写了所有输入字段。我不确定我是否错误地初始化了我的表单,但我很困惑为什么我的表单从未通过验证检查。
最后在验证检查打印出以下内容后用“
print(canada_tax_form.errors)
”打印到控制台,这让我相信我的表单正在被擦除。我怎样才能避免这种情况?
NOT VALID
<ul class="errorlist"><li>control_number<ul class="errorlist"><li>This field is required.</li></ul></li><li>item_number<ul class="errorlist"><li>This field is required.</li></ul></li><li>vendor_tax_code<ul class="errorlist"><li>This field is required.</li></ul></li><li>expiration_flag<ul class="errorlist"><li>This field is required.</li></ul></li><li>charge_category<ul class="errorlist"><li>This field is required.</li></ul></li><li>charge_desc_code<ul class="errorlist"><li>This field is required.</li></ul></li><li>country<ul class="errorlist"><li>This field is required.</li></ul></li><li>state<ul class="errorlist"><li>This field is required.</li></ul></li><li>charge_amount<ul class="errorlist"><li>This field is required.</li></ul></li><li>charge_uom<ul class="errorlist"><li>This field is required.</li></ul></li><li>charge_percentage<ul class="errorlist"><li>This field is required.</li></ul></li><li>apply_flag<ul class="errorlist"><li>This field is required.</li></ul></li><li>beg_del_date<ul class="errorlist"><li>This field is required.</li></ul></li><li>end_del_date<ul class="errorlist"><li>This field is required.</li></ul></li><li>rev_date<ul class="errorlist"><li>This field is required.</li></ul></li><li>rev_time<ul class="errorlist"><li>This field is required.</li></ul></li><li>est_date<ul class="errorlist"><li>This field is required.</li></ul></li><li>est_time<ul class="errorlist"><li>This field is required.</li></ul></li><li>program_id<ul class="errorlist"><li>This field is required.</li></ul></li><li>operator_id<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
在你的ajax中你发送以下内容:
data: JSON.stringify({
ajax_type: "tax_entry",
control_num: control_number,
item: item_number,
vend_tax: vendor_tax_code,
}),
但是,您的表格将会等待
1)数据值的键与表单定义中的字段具有相同的名称。根据错误来判断,它们的命名不同,例如 control_number 而不是 control_num,因此在请求的表单设置期间不会分配它们。POST
2)要填写的 CanadaTaxForm 的所有必填字段。由于您正在发送 POST 数据,因此不会读取您的初始字段,这可能会加剧这一情况。正如 docs 所说:这些值仅针对未绑定的表单显示,如果未提供特定值,它们不会用作后备值。
要解决此问题,您还可以在tax_records表中编写隐藏字段来保存CanadaTaxForm所需的任何其他数据,并在为ajax提交新值时捕获这些值作为“数据”。或者,如果用户无法真正更改其他数据,您可以缩减 CanadaTaForm,仅将提交的数据作为字段,在创建新对象时添加其他任何内容(如果没有,很难具体说明最佳课程)查看表格或模板)