大家好,这是皮爷给大家带来的最新的学习Python能干啥?之Django教程的进阶版。
在之前《用Django全栈开发》系列专辑里面,皮爷详细的阐述了如何编写一个完整的网站,具体效果可以浏览线上网站:Peekpa.com
从进阶篇开始,每一篇文章都是干货满满,干的不行。这一节,我们来说:如何让我们的网站对用户更加友好,不需要等待时间,利用Django REST Framework和Ajax实现。
Peekpa.com的官方地址:http://peekpa.com
获取整套教程源码唯一途径,关注『皮爷撸码』,回复『peekpa.com』
皮爷的每一篇文章,都配置相对应的代码。这篇文章的代码对应的Tag是“Advanced_10”。
前瞻回顾
上一节课我们已经讲述了如何使用Django REST framework来简单的实现我们的API接口,那么这一节,我们就来解决异步的问题。
不知道大家发现没有,现在几乎我们所有的CMS页面,还有我们数据中心的页面。点击逻辑基本都是点完之后,会有一个比较长的等待时间。
这里的时间是261ms,看似挺快,其实如果遇到数据库读取I/O拥堵,页面逻辑太过复杂,我们这里的数据时间还会更长。
我们这里的请求流程其实是下面这个样子的:
可以看到,请求页面,必须等到所有数据全部返回,一切都准备好之后,才会将结果返回给前端。
并不是像常规网站异步加载一样,点击之后,会有一个loading圈圈一直转,然后数据从后端返回之后在加载出来。
所以,今天我们就要使用Django + Django REST framework + Ajax + ArtTemplate 来实现Django页面的异步加载。
当然,这里小声逼逼一句,之后我们会前后端
结构介绍
上节课,我们通过Django REST framework来修改了我们的地震端口为http://127.0.0.1:8000/center/data/
那么我们就完全可以利用这个接口来实现异步请求。请求流程如下图:
可以看到,请求数据,现将页面返回,然后当页面加载完成之后,再通过Ajax调用后端接口,即上面的Json接口,在接口返回数据后,我们再将数据展示到前端。
技术要点
想要实现上面的流程,主要需要以下技术,放心,我们的文章都会介绍:
- Django REST framework,这个主要负责实现API接口,返回Json数据;
- Ajax,这个主要是在页面加载完成之后的数据请求;
- Art-template,这个主要负责动态的加载展示内容,当然网上还有其他框架可以选择,这里我们就先选择这个Art Template了。
其中,第一个东西我们上节内容已经完成了。所以我们接下里就是要编写JS文件还有HTML文件了。
修改页面
我们这里就拿我们的“日本地震信息”页面来做。首先我们要将我们的页面结构修改一下,将原来的内容展示区域,换成一个loading圈:
<section class="content">
<div class="container-fluid pt-4">
{% include 'base/loading.html' %}
<div class="row" id="content-block">
</div>
</div>
</section>
而这个loading.html是这样的:
<div class="flex-fill align-items-center justify-content-center text-center" id="loading-circle">
<div class="spinner-border" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
所以,这个时候,我们的页面就会变成这个样子:
只有中间一个圈圈。
接下来,我们需要创建一个center_manage.js
文件,然后在里面编写我们的请求逻辑。
这个文件创建路径front/src/js/
。由于代码比较长,所以我下面就只列出来关键
$(document).ready(function () {
....内容过多,省略....
}
function getDataFromServer(url, loadingCircle, contentBlock, callback) {
contentBlock.hide();
contentBlock.empty();
loadingCircle.show();
$.ajax({
url: url,
type: "get",
success: function (data) {
callback(data, loadingCircle, contentBlock);
loadingCircle.hide();
contentBlock.show();
}
})
}
这里面出发方法的时间点就是在:$(document).ready()
,即当页面加载完成之后。
方法其实很简单,就是显示和隐藏loading圈以及板块内容,当数据成功的时候,就回调显示方法。
这个回调方法中最重要的一块就是如何将请求回来的数据交给Art-template了。
var tpl = template('data-list', {'data': data} );
contentBlock.append(tpl);
就是这么简单,使用art template来创建一个template,然后直接操作dom,将template添加到指定的dom节点就可以。
上面展示的JavaScript代码,都是指局部核心代码,如果想要查看具体代码都修改了哪些,可以去文章源码里面查看,文章源码获取方式在文末。
接下来我们就是要看这个在html页面里面,是怎么编写art temlpate模板的:
<script id="data-list" type="text/html">
{% verbatim %}
<div class="col-sm-12">
<div class="card">
<div class="card-header">
<div class="p-2 d-flex">
<p class="h3">Japan Earth <small class="text-danger" style="font-size: 15px">DataSource:{{ if data.from_cache }}Cache{{ else }}Databse{{ /if }}</small></p>
<form action="" method="get" class="form-inline ml-auto">
<input type="text" value="{{ cur_fid }}" name="fid" hidden>
<div class="form-group mr-4">
<label for="title-input">标题:</label>
{{ if data.title }}
<input type="text" class="form-control" name="search" id="title-input"
placeholder="关键字"
value="{{ data.title }}">
{{ else }}
<input type="text" class="form-control" name="search" id="title-input"
placeholder="关键字">
{{ /if }}
</div>
<div class="form-group mr-4">
<button class="btn btn-primary">查询</button>
</div>
<div class="form-group">
<a href="?fid={{ curblock }}">清除查询</a>
</div>
</form>
</div>
</div>
<div class="card-body">
<div class="row">
{{ each data.list_data item }}
<div class="row col-sm-3 pl-1 pr-1 mb-4">
<div class="row col-sm-12">
<small>{{ item.jp_title }}</small>
</div>
<div class="row col-sm-12">
<a href="{{ item.jp_url }}">{{ item.jp_location }}</a>
</div>
<div class="row col-sm-12">
<small>{{ item.jp_level }}</small>
</div>
<div class="row col-sm-12">
<small>{{ item.jp_max_level }}</small>
</div>
<div>
{{ if item.jp_id }}
<a class="btn btn-primary badge" href="{% url 'center:jpearth_send_view' jp_id=item.jp_id %}">发送详情</a>
{{ /if }}
</div>
</div>
{{ /each }}
</div>
<!--省略分页的内容->
</div>
</div>
</div>
{% endverbatim %}
</script>
可以看到,具体的格式和步骤有以下几步:
- art-template是包裹在
<script>
标签里面的; -
script
标签里面的id值,和JavaScript文件里面的var tpl = template('data-list', {'data': data} );
是对应的; - 使用
{% verbatim %}
去掉渲染,这个必加; - 判断和循环语法,和原来的DLT不一样,这里必须使用
art-template
的语法。 - 判断的需要使用:
{{ if xxx条件 }}..{{else}}..{{ /if }}
; - 循环需要使用:
{{ each data.list_data item }}...{{ /each }}
;
关于ArtTemplate的语法部分,如果遇到不会写的地方,建议去查看一下官方文档:
http://aui.github.io/art-template/zh-cn/docs/index.html
文档里面写的非常详细,如果你之前有写过Django模板的经历,那么这个文档对你来说是不成问题的。
上面的HTML代码,只是展示的局部,如果感兴趣,可以去源码中查看具体修改了哪些内容,获取源码的方式,在文章最后有写。
最后别忘了在我们的{% block head %}
中引入我们写好的js文件和我们的art template文件:
{% block head %}
<script src="{% static 'arttemplate/template-web.js' %}"></script>
<script src="{% static 'js/center_manage.min.js' %}"></script>
{% endblock %}
这样,我们再来看一下效果:
可以看到,在我们的控制台,打印出来我们从Django REST framework创建的API获取到的数据,而且Networks里面,整个页面的加载也确实是分开进行的,所以,我们的异步请求就实现了。
这样实现的好处是,可以给用户更好的用户体验,不需要让用户长时间等待。
技术总结
最后总结一下,
如何使用Django + Ajax + Django REST framework + Art template来实现异步请求:
- 异步请求的目的就是为了减少用户等待的时间,能够先给用户一个反馈;
- 修改成异步请求的步骤,修改HTML和编写JavaScript两步
- 修改HTML,即加入Loading圈,然后再将之前显示数据的模块,按照ArtTemplate的语法格式修改,包裹在Script标签中;
- 编写Js文件,主要目的就是在
$(document).ready()
里面实现对后台接口的请求,请求使用Ajax; - 最后别忘了引入我们的JavaScript文件还有ArtTemplate依赖;
- 进阶篇的Django异步请求总结完毕。
获取整套教程源码唯一途径,关注『皮爷撸码』,回复『peekpa.com』
长按下图二维码关注,如文章对你有启发或者能够帮助到你,欢迎点赞,在看,转发三连走一发,这是对我原创内容输出的最大肯定。