Django Series(Django2.1.2 + Anaconda3)
(一)安装并配置 Django 环境 ||| 基于 Django 进行 Web 开发
(四)数据的增删改:用户提交数据,验证数据的有效性并传输至后台(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' %}"> </td>
<td valign="top" bgcolor="#F7F8F9">
<table width="100%" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td colspan="2" valign="top"> </td>
<td> </td>
<td valign="top"> </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"> </td><td> </td><td valign="top"> </td></tr>
<tr>
<td width="2%"> </td>
<td width="50%" class="left_txt">
<img src="{% static 'images/icon_mail.gif' %}" width="16" height="11"> 客户服务邮箱:pangkang@qq.com<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' %}"> </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)