我们在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的更多相关文章

  1. python工业互联网应用实战18—前后端分离模式之jquery vs vue

    前面我们分三章来说明了使用django template与jquery的差别,通过jquery如何来实现前后端的分离,同时再9章节使用vue.js 我们浅尝辄止的介绍了JQuery到vue的切换,由于 ...

  2. python工业互联网应用实战17—前后端分离模式之django template vs jquery3

    上一章节我们完成了"CRUD"的后面3个功能点,新增由于改动较大我们专门增加本章来阐述,主要是完成技术栈切换后,会发现模板的代码判断过多,逻辑过于复杂.对未来存在的扩展和维护友好性 ...

  3. Spring Cloud实战 | 最八篇:Spring Cloud +Spring Security OAuth2+ Axios前后端分离模式下无感刷新实现JWT续期

    一. 前言 记得上一篇Spring Cloud的文章关于如何使JWT失效进行了理论结合代码实践的说明,想当然的以为那篇会是基于Spring Cloud统一认证架构系列的最终篇.但关于JWT另外还有一个 ...

  4. AngularJS中在前后端分离模式下实现权限控制 - 基于RBAC

    一:RBAC 百科解释: 基于角色的访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注.在RBAC中,权限与角色相关联,用 ...

  5. Vue的学习总结之---Vue项目 前后端分离模式解决开发环境的跨域问题

    原文:https://blog.csdn.net/localhost_1314/article/details/83623526 在前后端分离的web开发中,我们与后台联调时,会遇到跨域的问题. 比如 ...

  6. python工业互联网应用实战2—从需求开始

    前言:随着国家工业2025战略的推进,工业互联网发展将会提速,将迎来一个新的发展时期,越来越多的企业开始逐步的把产线自动化,去年年底投产的小米亦庄的智能工厂就是一个热议的新闻.小米/华为智能工厂只能说 ...

  7. python工业互联网应用实战16-前后端分离模式之修改与删除

    前一章节介绍了List页面的JQuery技术栈的迁移,这一章节我们花一些篇幅来说说修改/查看页面的技术栈迁移.相对于List的获取数据,修改页面涉及到数据Post提交到后台更新数据库.我们仍旧小步迭代 ...

  8. python工业互联网应用实战3—模型层构建

    本章开始我们正式进入到实战项目开发过程,如何从需求分析获得的实体数据转到模型设计中来,变成Django项目中得模型层.当然,第一步还是在VS2019 IDE环境重创建一个工程项目,本文我们把工程名称命 ...

  9. python工业互联网应用实战1—SQL与ORM

    从sql到ORM应该说也是编程体系逐步演化的结果,通过类和对象更好的组织开个过程中遇到的各种业务问题,面向对象的解耦和内聚作为一套有效的方法论,对于复杂的企业应用而言确实能够解决实践过程中很多问题. ...

随机推荐

  1. 后台开发-核心技术与应用实践--TCP协议

    网络模型 为使不同计算机厂家的计算机能够互相通信,国际标准化组织 ISO 1981 年正式推荐了一个网络系统结构一一七层参考模型,也叫作开放系统互连模型. ISO 七层网络模型及其功能展示: 这个七层 ...

  2. 从源码剖析Go语言基于信号抢占式调度

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/485 本文使用的go的源码15.7 这一次来讲讲基于信号式抢占式调度 ...

  3. 201871030102-崔红梅 实验二 个人项目—— D{0-1}KP 项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 实验二作业链接 我的课程学习目标 1.熟练掌握将本地代码保存至GitHub中2.掌握折扣背包问题3.回顾动态规划算法和回溯算法4.对java语 ...

  4. Dynamics CRM邮箱配置

    Dynamics CRM对邮箱有很好的支持,开通邮箱后方便用户通过邮件进行Dynamics CRM的业务处理,同时也可以作为一直消息流提醒的手段应用于审批.通知等场景,可以做一些更深入的功能拓展. 本 ...

  5. 可读性友好的JavaScript:两个专家的故事

    每个人都想成为专家,但什么才是专家呢?这些年来,我见过两种被称为"专家"的人.专家一是指对语言中的每一个工具都了如指掌的人,而且无论是否有帮助,都一定要用好每一点.专家二也知道每一 ...

  6. Bounding Volume Hierarchies 加速结构

    背景   光线与物体求交是光线追踪的主要时间瓶颈.   如果不进行优化,则对每条光线,我们都需要遍历场景中的全部物体并求交.而现在想建模一个小物体的表面,往往要几千甚至几万个三角形,一个商业级产品,屏 ...

  7. ASP.NET Core扩展库之Http请求模拟

    如今,完全独立的业务应用几乎不存在,不管是在企业内部微服务之间的调用,还是与外部第三方服务的调用,Http的API交互是常见的场景,这些实际情况给我们的开发带来了比较大的挑战,一是第三方服务可能会牵制 ...

  8. Django 入门范例

    1. Django 介绍 2. Django 环境搭建 3. 模型(Model) 4. 站点管理 5. 视图(View) 6. 模板(Template) 1. Django 介绍 MVC 模型 大部分 ...

  9. Sql server注入一些tips

    sql server环境测试: 几个特性: 1.sql server兼容性可以说是最差的. 举例: select x from y where id=1 字符串查询 select x from y w ...

  10. 【Java】String、StringBuilder和StringBuffer

    [String] 首先,从String类的定义入手,可以看到String类是由final修饰,即不可变的,一旦创建出来就不可修改,因此首先明确,字符串的拼接.截取等操作都会产生新的字符串对象. 观察以 ...