用Django全栈开发(进阶篇)——10. Django + Django REST framework + Ajax + Art Templat实现异步请求

大家好,这是皮爷给大家带来的最新的学习Python能干啥?之Django教程的进阶版

在之前《用Django全栈开发》系列专辑里面,皮爷详细的阐述了如何编写一个完整的网站,具体效果可以浏览线上网站:Peekpa.com

从进阶篇开始,每一篇文章都是干货满满,干的不行。这一节,我们来说:如何让我们的网站对用户更加友好,不需要等待时间,利用Django REST Framework和Ajax实现。

Peekpa.com的官方地址:http://peekpa.com

获取整套教程源码唯一途径,关注『皮爷撸码』,回复『peekpa.com』

皮爷的每一篇文章,都配置相对应的代码。这篇文章的代码对应的Tag是“Advanced_10”。

title.jpeg

前瞻回顾

上一节课我们已经讲述了如何使用Django REST framework来简单的实现我们的API接口,那么这一节,我们就来解决异步的问题。

不知道大家发现没有,现在几乎我们所有的CMS页面,还有我们数据中心的页面。点击逻辑基本都是点完之后,会有一个比较长的等待时间。

001.png

这里的时间是261ms,看似挺快,其实如果遇到数据库读取I/O拥堵,页面逻辑太过复杂,我们这里的数据时间还会更长。

我们这里的请求流程其实是下面这个样子的:

002.png

可以看到,请求页面,必须等到所有数据全部返回,一切都准备好之后,才会将结果返回给前端。

并不是像常规网站异步加载一样,点击之后,会有一个loading圈圈一直转,然后数据从后端返回之后在加载出来。

所以,今天我们就要使用Django + Django REST framework + Ajax + ArtTemplate 来实现Django页面的异步加载。

当然,这里小声逼逼一句,之后我们会前后端

结构介绍

上节课,我们通过Django REST framework来修改了我们的地震端口为http://127.0.0.1:8000/center/data/

003.png

那么我们就完全可以利用这个接口来实现异步请求。请求流程如下图:

004.png

可以看到,请求数据,现将页面返回,然后当页面加载完成之后,再通过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>

所以,这个时候,我们的页面就会变成这个样子:

005.png

只有中间一个圈圈。

接下来,我们需要创建一个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 %}

这样,我们再来看一下效果:

006.png

007.png

可以看到,在我们的控制台,打印出来我们从Django REST framework创建的API获取到的数据,而且Networks里面,整个页面的加载也确实是分开进行的,所以,我们的异步请求就实现了。

这样实现的好处是,可以给用户更好的用户体验,不需要让用户长时间等待。

技术总结

最后总结一下,

如何使用Django + Ajax + Django REST framework + Art template来实现异步请求:

  1. 异步请求的目的就是为了减少用户等待的时间,能够先给用户一个反馈;
  2. 修改成异步请求的步骤,修改HTML和编写JavaScript两步
  3. 修改HTML,即加入Loading圈,然后再将之前显示数据的模块,按照ArtTemplate的语法格式修改,包裹在Script标签中;
  4. 编写Js文件,主要目的就是在$(document).ready()里面实现对后台接口的请求,请求使用Ajax;
  5. 最后别忘了引入我们的JavaScript文件还有ArtTemplate依赖;
  6. 进阶篇的Django异步请求总结完毕。

获取整套教程源码唯一途径,关注『皮爷撸码』,回复『peekpa.com』

长按下图二维码关注,如文章对你有启发或者能够帮助到你,欢迎点赞在看转发三连走一发,这是对我原创内容输出的最大肯定。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,056评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,842评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,938评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,296评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,292评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,413评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,824评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,493评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,686评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,502评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,553评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,281评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,820评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,873评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,109评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,699评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,257评论 2 341