python工业互联网应用实战15-前后端分离模式1
我们在13章节里通过监控界面讲了如何使用jquery的动态加载数据写法,通过简单案例来说明了如何实现动态的刷新监控界面的数据,本章我们将演示如何从Django模板加载数据逐步演化到前后端分离的异步数据加载和前端渲染主流开发方式,从而进一步实现前后端的解耦,提高Django开发Web应用的灵活性。
1.1. 修改任务列表模板
目前我们显示的任务列表是采用Django后台模板的方式加载数据的,要使用JQuery,同样采用探索编程方式,先实现前端加载模拟数据,Django模板只负责加载页面的基础架构,数据的渲染交由前端JQuery js脚本来实现加载模拟数据。
1.1.1. 修改tasks.html模板代码
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>任务列表</title>
</head>
<body>
<table id="id_task_table">
<tr>
<th>ID</th>
<th>任务号</th>
<th>源地址</th>
<th>目标地址</th>
<th>条码</th>
<th>状态</th>
<th>优先级</th>
<th>开始时间</th>
<th>结束时间</th>
<th>作业数量</th>
<th>操作</th>
</tr>
</table>
</body>
</html>
现在运行服务器,访问URL结果如下:

模板只只负责搭建要给页面的框架,数据通过JQuery来前端渲染。 页面的任务实例数据没有加载了,只显示了表格标题头。现在我们用JQuery脚本先给表格加载前端模式数据,先实现显示效果不变,逐步实现技术的切换。
1.1.2. JQuery动态添加任务列表行数据
JQuery脚本渲染代码如下:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>任务列表</title>
<link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<table id="id_task_table">
<tr>
<th>ID</th>
<th>任务号</th>
<th>源地址</th>
<th>目标地址</th>
<th>条码</th>
<th>状态</th>
<th>优先级</th>
<th>开始时间</th>
<th>结束时间</th>
<th>作业数量</th>
<th>操作</th>
</tr>
</table>
<script>
var row="";
row +="<tr>";
row +="<td>1</td>";
row +="<td>100</td>";
row +="<td>103</td>";
row +="<td>05-01-01</td>";
row += "<td>101001001008</td>";
row += "<td>未处理</td>";
row += "<td>正常</td>";
row += "<td>-</td>";
row += "<td>-</td>";
row += "<td>2021-01-26 05:58:28</td>";
row += "<td>0</td>";
row += "<td><a id='1-decompose' href='1/decompose/'>分解</a> <a id='1-start' href='1/start/'>下达</a> <a id='1-change' href='1/change/'>修改</a></td>";
row +="</tr>";
$("#id_task_table tbody").append(row);
</script>
</body>
</html>
运行效果,我们发现页面渲染结果增加一行我们模拟添加的行任务数据。这样基于JQuery动态添加任务行的基本效果就实现了,下一步需要做的就是如何通过JQuery异步调用从后台获取数据后再通过上面的脚本实现任务数据在列表的渲染。
1.2. 改造任务后台
页面端ajax异步加载任务数据,需要后台能够返回json格式封装的任务数据。同理,采用渐进式方式先直接返回模拟多个任务的json格式任务数据url taskGetList。
1.2.1. taskGetList url
文件Task/urls 增加taskGetList url,对应Task/views文件增加taskGetList 函数,代码如下:
文件:Task/urls.py
from django.urls import path,re_path
from Task import views
urlpatterns = [
path('', views.view_list,name='view_list'),
re_path('^(?P<pk>\d+)/start/$',views.start,name='start'),#①
re_path('^(?P<pk>\d+)/change/$',views.change,name='change'),#②
re_path('^(?P<pk>\d+)/decompose/$',views.decompose,name='decompose'),
path('taskGetList/', views.taskGetList,name='taskGetList'),
]
文件:Task/views.py
from django.http import JsonResponse ... def taskGetList(request):
tasks=[]
task= {'TaskId':1,'TaskNum':100,'Source':'103','Target':'05-01-01','Barcode':'101001001008','State':1,'Priority':1,\
'BeginDate':None,'EndDate':None,'SystemDate':'2021-01-26 05:58',}
tasks.append(task)
tasks.append({'TaskId':2,'TaskNum':101,'Source':'102','Target':'05-01-11','Barcode':'101001001009','State':1,'Priority':1,\
'BeginDate':None,'EndDate':None,'SystemDate':'2021-01-26 06:00',}) data={"rows":tasks,'total':len(tasks),'success':True} #① return JsonResponse( data); #②
标注①:返回数据json格式封装,rows具体的任务List,total 返回总长度,sucess 是否成功。标注②:采用JsonResponse响应方式返回。
运行结果如下:http://localhost:8080/task/taskGetList/

1.3. 再次重构页面代码
Django开发后端url服务是不是也相当的简单,好的,接下来我们就可以前台通过ajax访问这个url服务获取数据并渲染到页面了。参考1章的调用方式代码如下:
<script>
//每次页面加载,ajax请求获取任务列表数据
getData()
function getData() {
//异步从后台获得值
$.ajax({
url: "/task/taskGetList/", success: function (result) {
//d = JSON.parse(result);
d = result
for (const task of d.rows) {
var row="";
row +="<tr>";
row +="<td>"+task.TaskId+"</td>";
row +="<td>"+task.TaskNum+"</td>";
row +="<td>"+task.Source+"</td>";
row +="<td>"+task.Target+"</td>";
row += "<td>"+task.Barcode+"</td>";
row += "<td>"+task.State+"</td>";
row += "<td>"+task.Priority+"</td>";
row += "<td>"+task.BeginDate+"</td>";
row += "<td>"+task.EndDate+"</td>";
row += "<td>"+task.SystemDate+"</td>";
row += "<td>"+task.JobCount+"</td>";
row += "<td><a id='" + task.TaskId + "-decompose' href='"+task.TaskId +"/decompose/'>分解</a> <a id='"+task.TaskId +"-start' href='"+task.TaskId +"/start/'>下达</a> <a id='"+task.TaskId +"-change' href='"+task.TaskId +"/change/'>修改</a></td>";
row +="</tr>";
$("#id_task_table tbody").append(row);
}
}});
}
</script>
运行效果,页面渲染结果采用了接口返回的数据。

1.4. 返回model层数据
本章节到这一步就是通过model层返回数据库表里的数据了,也就是如何model list系列化为字典格式,这里我们先采用model_to_dict实现model数据字典化,然后通过JsonResponse返回json格式数据。
from django.forms.models import model_to_dict
... def taskGetList(request):
tasks = []
taskList=Task.objects.all()
for model in taskList:
modelJson = model_to_dict(model)
modelJson['SystemDate'] = model.SystemDate #①
modelJson['JobCount'] =model.job_set.count() #②
tasks.append(modelJson)
data={"rows":tasks,'total':len(tasks),'success':True}
return JsonResponse( data);
标注①:model_to_dict不会转换有默认值的属,人工直接转换。标注②:python django笔者用起来很爽很爽的一点啊,可以方便的动态属性。
现在run一下http://localhost:8080/task/taskGetList/ 结果变成了这样:

改进一下日期格式,采用格式化函数格式化日期。
from django.forms.models import model_to_dict
... def taskGetList(request):
tasks = []
taskList=Task.objects.all()
for model in taskList:
modelJson = model_to_dict(model)
modelJson['SystemDate'] = model.SystemDate.strftime('%Y-%m-%d %H:%M:%S') #①
modelJson['JobCount'] =model.job_set.count()
tasks.append(modelJson)
data={"rows":tasks,'total':len(tasks),'success':True}
return JsonResponse( data);
标注①:采用strftime('%Y-%m-%d %H:%M:%S')把日期显示为24小时格式的。
现场运行开发服务,访问刷新http://localhost:8080/task/ 我们得到了代码重构前得效果,任务列表返回了数据库表的数据,但是一些字段没显示对照的中文函数
新版本

旧版本

进一步完善的服务端代码:
from django.forms.models import model_to_dict
def taskGetList(request):
tasks = []
taskList=Task.objects.all()
for model in taskList:
modelJson = model_to_dict(model)
modelJson['SystemDate'] = model.SystemDate.strftime('%Y-%m-%d %H:%M:%S')
modelJson['JobCount'] =model.JobCount() #①
modelJson['Priority'] =model.get_Priority_display()#②
modelJson['State'] =model.get_State_display()
tasks.append(modelJson)
data={"rows":tasks,'total':len(tasks),'success':True}
return JsonResponse( data);
标注①:JobCount移入到Model层,构成model的一个属性函数。标注②:直接返回优先级值的对照信息。
class Task(models.Model):
... def JobCount(self):
return self.job_set.count() JobCount.short_description='作业数量'
客户端代码:
<script>
getData() function getData() {
//模拟异步从后台获得值
$.ajax({
url: "/task/taskGetList/", success: function (result) {
//d = JSON.parse(result);
d = result
for (const task of d.rows) {
var row="";
row +="<tr>";
row +="<td>"+task.TaskId+"</td>";
row +="<td>"+task.TaskNum+"</td>";
row +="<td>"+task.Source+"</td>";
row +="<td>"+task.Target+"</td>";
row += "<td>"+task.Barcode+"</td>";
row += "<td>"+task.State+"</td>";
row += "<td>"+task.Priority+"</td>";
row += "<td>"+(task.BeginDate?task.BeginDate:'-')+"</td>";
row += "<td>"+(task.EndDate?task.EndDate:'-')+"</td>";
row += "<td>"+task.SystemDate+"</td>";
row += "<td>"+task.JobCount+"</td>";
row += "<td><a id='" + task.TaskId + "-decompose' href='"+task.TaskId +"/decompose/'>分解</a> <a id='"+task.TaskId +"-start' href='"+task.TaskId +"/start/'>下达</a> <a id='"+task.TaskId +"-change' href='"+task.TaskId +"/change/'>修改</a></td>";
row +="</tr>";
$("#id_task_table tbody").append(row);
}
}});
}
</script>
1.5. 小结
通过本章节内容,我们阐述了如何实现服务端与客户端分离的写法,并仍然采用稳步的渐进式改造方案,采用小步快跑的方式完成本次迭代。最后,我们在功能不变的前提下,完成了技术栈的迁移,把基于模板页渲染的django变成了基于模板框架js异步渲染的主流编程模式,下一章节我们将演示如何如何把编辑页面也进阶到前端渲染。
python工业互联网应用实战15-前后端分离模式1的更多相关文章
- python工业互联网应用实战18—前后端分离模式之jquery vs vue
前面我们分三章来说明了使用django template与jquery的差别,通过jquery如何来实现前后端的分离,同时再9章节使用vue.js 我们浅尝辄止的介绍了JQuery到vue的切换,由于 ...
- python工业互联网应用实战17—前后端分离模式之django template vs jquery3
上一章节我们完成了"CRUD"的后面3个功能点,新增由于改动较大我们专门增加本章来阐述,主要是完成技术栈切换后,会发现模板的代码判断过多,逻辑过于复杂.对未来存在的扩展和维护友好性 ...
- Spring Cloud实战 | 最八篇:Spring Cloud +Spring Security OAuth2+ Axios前后端分离模式下无感刷新实现JWT续期
一. 前言 记得上一篇Spring Cloud的文章关于如何使JWT失效进行了理论结合代码实践的说明,想当然的以为那篇会是基于Spring Cloud统一认证架构系列的最终篇.但关于JWT另外还有一个 ...
- AngularJS中在前后端分离模式下实现权限控制 - 基于RBAC
一:RBAC 百科解释: 基于角色的访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注.在RBAC中,权限与角色相关联,用 ...
- Vue的学习总结之---Vue项目 前后端分离模式解决开发环境的跨域问题
原文:https://blog.csdn.net/localhost_1314/article/details/83623526 在前后端分离的web开发中,我们与后台联调时,会遇到跨域的问题. 比如 ...
- python工业互联网应用实战2—从需求开始
前言:随着国家工业2025战略的推进,工业互联网发展将会提速,将迎来一个新的发展时期,越来越多的企业开始逐步的把产线自动化,去年年底投产的小米亦庄的智能工厂就是一个热议的新闻.小米/华为智能工厂只能说 ...
- python工业互联网应用实战16-前后端分离模式之修改与删除
前一章节介绍了List页面的JQuery技术栈的迁移,这一章节我们花一些篇幅来说说修改/查看页面的技术栈迁移.相对于List的获取数据,修改页面涉及到数据Post提交到后台更新数据库.我们仍旧小步迭代 ...
- python工业互联网应用实战3—模型层构建
本章开始我们正式进入到实战项目开发过程,如何从需求分析获得的实体数据转到模型设计中来,变成Django项目中得模型层.当然,第一步还是在VS2019 IDE环境重创建一个工程项目,本文我们把工程名称命 ...
- python工业互联网应用实战1—SQL与ORM
从sql到ORM应该说也是编程体系逐步演化的结果,通过类和对象更好的组织开个过程中遇到的各种业务问题,面向对象的解耦和内聚作为一套有效的方法论,对于复杂的企业应用而言确实能够解决实践过程中很多问题. ...
随机推荐
- pip软件包管理工具介绍及基本使用
pip软件包管理工具介绍及基本使用 一分耕耘,一分收获,要收获得好,必须耕耘得好.-- 徐特立 一.pip软件包管理工具介绍: 定义:pip是Python包管理工具 作用:对Python包的查找.下载 ...
- Windows下解析命令行参数
linux通常使用GNU C提供的函数getopt.getopt_long.getopt_long_only函数来解析命令行参数. 移植到Windows下 getopt.h #ifndef _GETO ...
- OCPC产品初探
OCPC即Optimization CPC,今天我们就来看看它的Optimizaton在哪儿. 在广告模型初探(一)中我们就曾提到过,互联网广告的本质其实就是流量的买卖.是广告主.媒体方以及用户三方之 ...
- [面试仓库]CSS面试题汇总-图文样式篇
图文样式这,我们挑了一个最常见的来说:line-height继承问题.从三个方面来考虑: 如果是具体的数值,则继承该数值 body{ font-size:32px; line-height:40p ...
- 软工案例分析作业-CSDN
项目 内容 这个作业属于哪个课程 2021春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 案例分析作业要求 我在这个课程的目标是 提升软件开发能力与团队意识 这个作业在哪个具体方面帮助我实 ...
- Azure Digital Twins(2)- 在本地使用ADT Explorer 管理数字孪生
本文介绍: 在本地运行ADT Explorer 并连接Azure Digital Twins 实例: 使用 VS CODE DTDL插件开发第一个 模型文件: ADT Explorer的几个基本功能: ...
- 如何建立一个足够安全的SSH连接?
1 概述 使用SSH连接服务器是一件很平常的事,但是,连接是否足够安全是一个令人担忧的问题.本文从如下几个方面介绍了如何建立一个足够安全的SSH连接: 端口 协议 用户 密码 密钥对 ssh-agen ...
- 2. linux下如何上传和下载文件
一. 安装工具包 yum install -y lrzsz lrzsz是一个unix通信套件提供的X,Y,和ZModem文件传输协议,可以用在windows与linux 系统之间的文件传输,体积小速度 ...
- js的13种继承
js继承的13种方式 也可以说只有12种,ES6的extend 也是12种方法之一-寄生继承的语法糖 1.原型链法 代码示例 Child.prototype = new Parent(); 所属模式: ...
- 超详细网站博客域名和二级域名、子域名升级HTTPS免费申请SSL证书配置nginx指南
随着互联网的飞速发展,我们的工作生活已经离不开互联网,HTTP虽然使用极为广泛, 但是存在不小的安全缺陷, 主要是其数据的明文传送和消息完整性检测的缺乏, 而这两点恰好是网络支付,网络交易等网站应用中 ...