1. 程式人生 > >【Django Series - 04】資料的增刪改:使用者提交資料,驗證資料的有效性並傳輸至後臺(jQuery.post)

【Django Series - 04】資料的增刪改:使用者提交資料,驗證資料的有效性並傳輸至後臺(jQuery.post)

Django Series(Django2.1.2 + Anaconda3)

(一)安裝並配置 Django 環境 ||| 基於 Django 進行 Web 開發

(二)Django 基礎知識:語法、教程

(三)使用者管理模組:建立使用者、登入、退出

(四)資料的增刪改:使用者提交資料,驗證資料的有效性並傳輸至後臺(jQuery.post、jQuery.getJSON)

(五)基於 "xlsxwriter  + BytesIO"(Python3)生成 Excel 報表 ||| Python2 StringIO.StringIO()


說明:本系列教程根據最近實踐過程進行整理、總結和分享。由於時間和精力有限,發表時內容分析部分可能不是很完整

,後續有時間會慢慢補充。同時!!也希望感興趣的同學可以提出一些細節問題和建議,我會根據這些問題進一步整理和完善哈。

更新日誌:

20181019:發表第一版,主要以程式碼分享為主;知識點分析較為粗略。


知識點分析:

 

實現程式碼:

XXX.html

{% extends "base.html" %}
{% load staticfiles %}

{% block title %}
XXXX管理系統
{% endblock %}

{% block style %}
{% endblock %}

{% block content %}
<div>
    <table width="100%" border="0" cellpadding="0" cellspacing="0">
        <tr>
            <td width="17" valign="top" background="{% static 'images/mail_left_bg.gif' %}">
                <img src="{% static 'images/left_top_right.gif' %}" width="17" height="29" />
            </td>
            <td valign="top" background="{% static 'images/content_bg.gif' %}">
                <table width="100%" height="31" border="0" cellpadding="0" cellspacing="0" background="{% static 'images/content_bg.gif' %}">
                    <tr>
                        <td height="31">
                            <div class="title">其他費用:</div>
                        </td>
                    </tr>
                </table>
            </td>
            <td width="16" valign="top" background="{% static 'images/mail_right_bg.gif' %}">
                <img src="{% static 'images/nav_right_bg.gif' %}" width="16" height="29" />
            </td>
        </tr>

        <tr>
            <td valign="middle" background="{% static 'images/mail_left_bg.gif' %}">&nbsp;</td>
            <td valign="top" bgcolor="#F7F8F9">
                <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0">
                    <tr>
                        <td colspan="2" valign="top">&nbsp;</td>
                        <td>&nbsp;</td>
                        <td valign="top">&nbsp;</td>
                    </tr>

                    <tr>
                        <td colspan="4" valign="top">
                            <table class="table table-bordered table-hover DataTable_class">
                                <thead>
                                     <tr>
                                        <th style="text-align: center;">工作令號</th>
                                        <th style="text-align: center;">專案名稱</th>
                                        <th style="text-align: center;">其他費用型別</th>
                                        <th style="text-align: center;">其他費用款項</th>
                                        <th style="text-align: center;">發起者</th>
                                        <th style="text-align: center;">錄入人員</th>
                                        <th style="text-align: center;">發起日期</th>
                                        <th style="text-align: center;">其他費用說明</th>
                                        <th style="text-align: center;">操作</th>
                                     </tr>
                                 </thead>

                                 <tbody>
                                 {% for others in OtherCost_list %}
                                        <tr>
                                            <th style="text-align: center;">{{ others.proj_id }}</th>
                                            <th style="text-align: center;">{{ others.proj_name }}</th>
                                            <th style="text-align: center;">{{ others.other_cost_type }}</th>
                                            <th style="text-align: center;">{{ others.other_cost|floatformat:"2" }}</th>
                                            <th style="text-align: center;">{{ others.proposer }}</th>
                                            <th style="text-align: center;">{{ others.inputer }}</th>
                                            <th style="text-align: center;">{{ others.proposer_date|date:"Y-m-d" }}</th>
                                            <th style="text-align: center;">{{ others.other_cost_explain }}</th>
                                            <th style="text-align: center;">
                                                <a onclick="fun_other_delete('{{ others.other_cost_type }}', '{{ others.proposer}}')" style="cursor:pointer;">
                                                    <span class="glyphicon glyphicon-remove" title="刪除資料"></span>
                                                </a>
                                            </th>
                                        </tr>
                                    {% endfor %}
                                 </tbody>
                            </table>
                        </td>
                    </tr>

                    <tr>
                        <td colspan="4" valign="top">
                            <div class="panel" style="border: 1px solid #e0e0e0; margin-top: 20px;">
                                <div class="panel-heading">
                                    <label style="font-size: 16px;">項目錄入員 -【{{proj_name}}】專案其他費用更新:</label>
                                    <a href="{% url 'app_ManageSystem:Modify_gather' proj_id %}" style="float: right;" title="返回">
                                        <span class="glyphicon glyphicon-repeat" style="font-size: 15px;"></span>
                                    </a>
                                </div>
                                <div class="panel-body" style="padding:0px 10px;">
                                    <table class="table input_style" border="0" cellspacing="0" cellpadding="0">

                                        <tr>
                                            <th>其他費用型別:</th>
                                            <td>
                                                <select id="other_cost_type" style="width:300px; height: 30px;">
                                                    {% for item in other_cost_type_list %}
                                                        <option id ="{{item.IndicatorName}}">{{item.IndicatorName}}</option>
                                                    {% endfor %}
                                                </select>
                                            </td>
                                        </tr>

                                        <tr>
                                            <th>其他費用款項(元):</th>
                                            <td><input type="text" id="other_cost" style="width:300px; height: 30px;"></td>
                                        </tr>

                                        <tr>
                                            <th>發起者:</th>
                                            <td><input type="text" id="proposer" style="width:300px; height: 30px;"></td>
                                        </tr>
                                        
                                        <tr>
                                            <th>發起日期:</th>
                                            <td><input type="date" id="proposer_date" style="width:300px; height: 30px;"></td>
                                        </tr>

                                        <!-- 
                                        <tr>
                                            <th>錄入人員:</th>
                                            <td><input type="text" id="inputer" style="width:300px; height: 30px;"></td>
                                        </tr> -->

                                        <tr>
                                            <th>其他費用說明:</th>
                                            <td><input type="text" id="other_cost_explain" style="width:600px; height: 30px;"></td>
                                        </tr>
                                    </table> 
                                </div>
                            </div>
                        </td>
                    </tr>

                    <tr>
                        <td></td>
                        <td width="100%" style="text-align: center;">
                            <input id="newBtn_others" class="btn-sm btn-default" type="button" value="確認更新">
                        </td>
                    </tr>

                    <tr height="20"><td colspan="2" valign="top">&nbsp;</td><td>&nbsp;</td><td valign="top">&nbsp;</td></tr>
                    <tr>
                        <td width="2%">&nbsp;</td>
                        <td width="50%" class="left_txt">
                            <img src="{% static 'images/icon_mail.gif' %}" width="16" height="11"> 客戶服務郵箱:
[email protected]
<br /> <img src="{% static 'images/icon_phone.gif' %}" width="17" height="14"> 官方網站:<a href="http://www.baidu.com/" target="_blank">寶潤石業有限公司</a> </td> </tr> </table> </td> <td background="{% static 'images/mail_right_bg.gif' %}">&nbsp;</td> </tr> <tr> <td valign="bottom" background="{% static 'images/mail_left_bg.gif' %}"> <img src="{% static 'images/buttom_left.gif' %}" width="17" height="17" /> </td> <td background="{% static 'images/buttom_bgs.gif' %}"> <img src="{% static 'images/buttom_bgs.gif' %}" width="17" height="17"> </td> <td valign="bottom" background="{% static 'images/mail_right_bg.gif' %}"> <img src="{% static 'images/buttom_right.gif' %}" width="16" height="17" /> </td> </tr> </table> </div> {% endblock %} {% block other_script %} <script type="text/javascript"> jQuery(document).ready(function() { // console.log("hello world..."); // 建立專案表 jQuery("#newBtn_others").bind("click", function(){ var other_cost_type = jQuery("#other_cost_type option:selected").text(); var other_cost = jQuery("#other_cost").val(); var proposer = jQuery("#proposer").val(); var proposer_date = jQuery("#proposer_date").val(); var other_cost_explain = jQuery("#other_cost_explain").val(); var operator = "add_update"; // console.log(other_cost_type); // console.log(other_cost); // console.log(proposer); // console.log(proposer_date); // console.log(other_cost_explain); if (null_alert(other_cost_type, "其他費用型別") && null_alert(other_cost, "其他費用款項") && IsNum(other_cost, "其他費用款項") && null_alert(proposer, "其他費用款項的發起者") && null_alert(proposer_date, "其他費用款項的發起日期") && null_alert(other_cost_explain, "其他費用款項的說明")){ jQuery.post("{% url 'app_ManageSystem:Modify_others' proj_id %}", { "other_cost_type" : other_cost_type, "other_cost" : other_cost, "proposer" : proposer, "proposer_date" : proposer_date, // "inputer" : inputer, "other_cost_explain" : other_cost_explain, "operator" : operator, }, function(ret){ if (ret == "successful"){ alert("新增/修改成功!發起者【" + proposer + "】的其他費用款項。"); window.location.reload(); }else{ alert("新增失敗!發起者【" + proposer + "】的其他費用款項。"); } }); } }); }); // 刪除 function fun_other_delete(other_cost_type, proposer){ if (confirm("確定刪除【" + other_cost_type + "】?")){ var operator = "delete"; // console.log(other_cost_type); // console.log(proposer); jQuery.post("{% url 'app_ManageSystem:Modify_others' proj_id %}", { "other_cost_type" : other_cost_type, "proposer" : proposer, "operator" : operator, }, function(ret){ if(ret == "successful"){ alert("刪除成功【" + other_cost_type + "】。"); window.location.reload(); }else{ alert("刪除失敗【" + other_cost_type + "】。"); } }); // end post } } </script> {% endblock %}

提交資料、修改資料:

1. 使用者在輸入框寫入相關的資料並點選“確認更新”;

2. 資料校驗:首先通過js獲取使用者輸入的每個資料,並根據實際情況進行校驗(不能為空、全部為數字、數字不能以0開頭等等);

3. 滿足資料合法之後,通過 jQuery.post 提交至後臺,並指定對應的 url(為了呼叫 views.py 中指定的函式);

4. django後臺接受由前端提交(post)過來的資料,可以選擇再次驗證資料的有效性;然後將資料儲存(save)或者更新(update)到相關的表中;

5. 讀取表內容,返回前端並展示資料。

if request.method == 'POST':

	other_cost_type = request.POST.get('other_cost_type')
	proposer = request.POST.get('proposer')
	operator = request.POST.get('operator')

	if operator == "add_update":
		
		other_cost = request.POST.get('other_cost')
		proposer_date = request.POST.get('proposer_date')
		# inputer = request.POST.get('inputer')
		inputer = request.session.get("NickName")
		other_cost_explain = request.POST.get('other_cost_explain')

		if OtherCost_info.objects.filter(proj_id = proj_id, other_cost_type = other_cost_type, proposer = proposer).exists():
			OtherCost_info.objects.filter(proj_id = proj_id, other_cost_type = other_cost_type, proposer = proposer).update(
										other_cost = other_cost, proposer_date = proposer_date, inputer = inputer, other_cost_explain = other_cost_explain)
		else:
			## 寫入資料庫
			obj = OtherCost_info.objects.get_or_create(proj_id = proj_id, proj_name = proj_name, other_cost_type = other_cost_type, other_cost = other_cost, 
													proposer = proposer, proposer_date = proposer_date, inputer = inputer, other_cost_explain = other_cost_explain)[0]
			obj.save()

刪除資料:

if request.method == 'POST':

	other_cost_type = request.POST.get('other_cost_type')
	proposer = request.POST.get('proposer')
	operator = request.POST.get('operator')

	if operator == "delete":
		if OtherCost_info.objects.filter(proj_id = proj_id, other_cost_type = other_cost_type, proposer = proposer).exists():
			OtherCost_info.objects.filter(proj_id = proj_id, other_cost_type = other_cost_type, proposer = proposer).delete()
			hcq_write(request.session.get('log_file_path'), True, False, "[{}({})]【{}】刪除成功".format(
									request.session.get('UserName'), request.session.get('RoleTypeID'), other_cost_type))

veiws.py 功能完整程式碼

### 專案其他費用
@csrf_exempt
def Modify_others(request, proj_id):

	context = {}

	UserName = request.session.get('UserName')
	if UserName != '' and UserName != None:
		print(UserName)
		if BRsystemUser.objects.filter(UserName = UserName).exists():
			user = BRsystemUser.objects.get(UserName = UserName)
			context["UserName"] = request.session.get("UserName")
			context["RoleTypeID"] = request.session.get("RoleTypeID")
			context["NickName"] = request.session.get("NickName")
	else:
		return HttpResponseRedirect('/app_ManageSystem/Login')

	
	if Proj_info.objects.filter(proj_id = proj_id).exists():
		proj_name = Proj_info.objects.get(proj_id = proj_id).proj_name
	
	context["proj_id"] = proj_id
	context["proj_name"] = proj_name

	if request.method == 'POST':

		other_cost_type = request.POST.get('other_cost_type')
		proposer = request.POST.get('proposer')
		operator = request.POST.get('operator')

		if operator == "add_update":
			
			other_cost = request.POST.get('other_cost')
			proposer_date = request.POST.get('proposer_date')
			# inputer = request.POST.get('inputer')
			inputer = request.session.get("NickName")
			other_cost_explain = request.POST.get('other_cost_explain')

			if OtherCost_info.objects.filter(proj_id = proj_id, other_cost_type = other_cost_type, proposer = proposer).exists():
				OtherCost_info.objects.filter(proj_id = proj_id, other_cost_type = other_cost_type, proposer = proposer).update(
											other_cost = other_cost, proposer_date = proposer_date, inputer = inputer, other_cost_explain = other_cost_explain)
			else:
				## 寫入資料庫
				obj = OtherCost_info.objects.get_or_create(proj_id = proj_id, proj_name = proj_name, other_cost_type = other_cost_type, other_cost = other_cost, 
														proposer = proposer, proposer_date = proposer_date, inputer = inputer, other_cost_explain = other_cost_explain)[0]
				obj.save()

		elif operator == "delete":
			if OtherCost_info.objects.filter(proj_id = proj_id, other_cost_type = other_cost_type, proposer = proposer).exists():
				OtherCost_info.objects.filter(proj_id = proj_id, other_cost_type = other_cost_type, proposer = proposer).delete()
				hcq_write(request.session.get('log_file_path'), True, False, "[{}({})]【{}】刪除成功".format(
										request.session.get('UserName'), request.session.get('RoleTypeID'), other_cost_type))

		## 更新當前專案資訊表:Cur_Projects
		try:
			OtherCost_list = OtherCost_info.objects.filter(proj_id = proj_id)
			other_total_cost = 0
			for OtherCost in OtherCost_list:
				other_cost = OtherCost.other_cost
				# print("proposer = {}, material_cost = {}".format(OtherCost.proposer, other_cost))
				if str_validate(other_cost):
					other_total_cost += float(other_cost)

			## update:出貨總收入、工人總費用
			Cur_Projects.objects.filter(proj_id = proj_id).update(other_total_cost = other_total_cost)

			## 更新總成本、收支平衡
			update_TotalIncome_Balance(request, proj_id)

			response = HttpResponse()
			response.write("successful")
			return response


		except Exception as e:
			response = HttpResponse()
			response.write("failure")
			return response

	## 獲取資料庫的資料,並顯示返回前端
	try:
		OtherCost_list = OtherCost_info.objects.filter(proj_id = proj_id)
		context["OtherCost_list"] = OtherCost_list

		if IndicatorSetting.objects.filter(IndicatorType = "04").exists():
			other_cost_type_list = IndicatorSetting.objects.filter(IndicatorType = "04")
			context["other_cost_type_list"] = other_cost_type_list

	except Exception as e:
		raise
	finally:
		pass

	return render(request, 'Modify_others.html', context)