从零开始用 Flask 搭建一个网站(二) 介绍了有关于数据库的运用,接下来我们在完善一下数据在前端以及前端到后端之间的交互。本节涉及到前端,因此也会讲解一下 jinja2 模板、jQuery、ajax 等用法。

下面我们来创建两个界面,一个可以新建 channel,并显示,另一个可以创建 integration,并且可以绑定一个之前创建的 channel。

post2channel.html

  1. {% extends "base.html" %}
  2. {% import "bootstrap/wtf.html" as wtf %}
  3. {% block head %}
  4. {{ super() }}
  5. <link rel="stylesheet" href="{{ url_for('static', filename='css/post2channel.css') }}">
  6. <link rel="stylesheet" href="{{ url_for('static', filename='css/toastr.css') }}">
  7. <script type="text/javascript" src="{{ url_for('static', filename= 'js/jquery.min.js') }}"></script>
  8. <script type="text/javascript" src="{{ url_for('static', filename='js/toastr.js') }}"></script>
  9. <script type="text/javascript" src="{{ url_for ('static', filename='js/')}}"></script>
  10. {% endblock %}
  11. {% block title %}极光宝盒-创建集成{% endblock %}
  12. {% block navbar %}
  13. <div id="navigationbar"></div>
  14. {{ super() }}
  15. {% endblock %}
  16. ...

我们从第一行开始来讲解一下这个模板,第一句

  1. {% extends "base.html" %}

从字面上可以明白这个模板继承了 base.html 模板,使用 {% %} 是 jinja2 模板的语法,表示语句块,还有一种分隔符 {{ }} ,表示变量,通常用来在模板上显示。接下来是

  1. {% block head %}

可以看到也是比较容易理解的语法,block 后接一个 block name,表示一个块开始的声明,结束的时候用 {% end %} 即可。在块中可以使用普通的 HTML 语法。{{ super() }} 表示继承父模板的块声明,这里指继承 base.html 中声明的 head 块。接下来是 css 和 js 文件的引用。此页面使用了 toastr 来显示通知,类似于 Android 中的 Toast,有兴趣的可以了解一下它的详细用法。

接下来是HTML代码,有一个下拉输入框和按钮。

  1. <ul id="content" class="dropdown-menu dropdown-menu-right">
  2. {% for channel in channels %}
  3. <li id="{{ channel }}" class="channel_class"><a>{{ channel }}</a></li>
  4. {% endfor %}
  5. </ul>

以上代码就是下拉输入框中的数据来源,用了一个for循环来遍历 channels 列表,并且用 li 包裹每个元素,这也是模板常见的用法。channels 是在视图函数中传过来的。

auth/views.py

  1. @auth.route('/new/post_to_channel', methods=['GET'])
  2. def post_to_channel():
  3. developer = get_developer()
  4. dev_key = developer.dev_key
  5. channels = get_channel_list()
  6. return render_template('auth/new/post2channel.html', **locals())

remder_template 的第二个参数表明,渲染这个 post2channel.html 页面的时候,把以上所有的变量都传递到页面中,这样就可以使用 {{ }} 模板语法拿到。接下来回到 post2channel.html, 看到部分:

  1. $('#create_integration_btn').click(function () {
  2. var channel = $('#selected_channel').val();
  3. console.log('create integration, channel: ' + channel);
  4. if (channel != '') {
  5. $.ajax({
  6. type: "POST",
  7. contentType: "application/json; charset=utf-8",
  8. url: "../../v1/developers/{{ dev_key }}/integrations",
  9. data: JSON.stringify({channel: channel}),
  10. success: function (data) {
  11. if (data != undefined) {
  12. if (data["token"]) {
  13. window.location.href = '/auth/manage/create_integration/' + data["integration_id"] + '/' + data["token"] + '/' + channel
  14. }
  15. } else {
  16. toastr.error("服务器异常");
  17. }
  18. },
  19. error: function (error) {
  20. console.log(error);
  21. toastr.error("创建失败");
  22. },
  23. dataType: "json"
  24. })
  25. }
  26. })

这是创建集成按钮的逻辑,用 jQuery 的 ajax 发送 post 请求,以 json 格式将输入框中的 channel 值传到 url 表明的视图函数。这里的 url 是相对路径。在 ajax 中有 success 和 error 两个函数,分别是请求成功和失败的回调函数。下面看到这个请求的视图函数,我们来看看视图函数是如何处理从页面传过来的数据。

api_1_0/developers.py

  1. # 添加一个集成,并返回 integration_id ,如果 channel 已存在,直接绑定该 channel, 否则新建一个 channel@api.route('/developers/<dev_key>/integrations', methods=['POST'])
  2. def create_integrations(dev_key):
  3. # 先判断一下传过来的 json 数据是否符合要求
  4. if not request.json or not 'channel' in request.json:
  5. print("request json error")
  6. abort(400)
  7. #从数据库得到 developer
  8. developer = Developer.query.filter_by(dev_key=dev_key).first()
  9. if developer is None:
  10. print("developer not found")
  11. abort(400)
  12. #以下省略
  13. ...
  14. #最后返回相关数据
  15. return jsonify({'integration_id': new_integration_id,
  16. 'token': token.decode('utf-8')}), 201

以上代码创建成功后也返回了一个 json,这样在 success 的回调函数中就能得到这个数据,用于在跳转到其他界面的时候做一些初始化操作。即以下代码:

  1. if (data != undefined) {
  2. if (data["token"]) {
  3. window.location.href = '/auth/manage/create_integration/' + data["integration_id"] + '/' + data["token"] + '/' + channel
  4. }
  5. }

这里将参数放到 url 中,调用了对应的视图函数:

auth/views.py

  1. @auth.route('/manage/create_integration/<string:integration_id>/<string:token>/<string:channel>', methods=['GET', 'POST'])
  2. def create_integration(integration_id, token, channel):
  3. integration = Integration.query.filter_by(integration_id=integration_id).first()
  4. channels = get_channel_list()
  5. developer = get_developer()
  6. dev_key = developer.dev_key
  7. return render_template('auth/create.html', **locals())

可以看到上面的参数就是从 post2channel 页面传过来的,并且还从数据库中查询到对应的 integration,然后将相关数据传到 create.html,让后者渲染页面。

我们通过一个例子看到数据在前端和后端、前端之间的交互。总结一下,无非就是在前端页面中发送请求,然后在视图函数中操作数据库,并且返回相关数据,回调到前端页面中,最后在回调中调用另一个视图函数,在跳转页面时利用得到的数据渲染页面。一切就是这么简单,没什么黑魔法!源码在 github 上。下一节介绍一下 flask_oauthlib 的用法,学习一下如何使用 oath2 第三方授权登录以及调用提供方的相关 API。


作者:KenChoi - 极光

原文:从零开始用 Flask 搭建一个网站(三)

知乎专栏:极光日报

从零开始用 Flask 搭建一个网站(三)的更多相关文章

  1. 从零开始用 Flask 搭建一个网站(一)

    前言 笔者之前未接触过 Python,只是略懂一点前端,所以说从零开始也相差无几吧.Flask 是一个轻量级的基于 Python 的框架,但是扩展性非常良好(Github 上 22000 多个 sta ...

  2. 从零开始用 Flask 搭建一个网站(二)

    从零开始用 Flask 搭建一个网站(一) 介绍了如何搭建 Python 环境,以及 Flask 应用基本项目结构.我们要搭建的网站是管理第三方集成的控制台,类似于 Slack. 本篇主要讲解数据如何 ...

  3. 从零开始用 Flask 搭建一个网站(四)

    前言 从零开始用 Flask 搭建一个网站(三) 介绍了网页前端与后端.前端与前端之间数据的交流.本节主要介绍一下如何应用 Flask-OAuthlib, 使用 Flask-OAuthlib 就可以轻 ...

  4. Python Flask搭建一个视频网站实战视频教程

    点击了解更多Python课程>>> Python Flask搭建一个视频网站实战视频教程 第1章 课程介绍 第2章 预备开发环境 第3章 项目分析.建立目录及模型规划 第4章 建立前 ...

  5. 05、(通过nat123软件) 实现用自己电脑搭建一个网站

    (通过nat123软件) 实现用自己电脑搭建一个网站 准备: Tomcat:这个是web容器,其实有了这个就已经让电脑成为服务器了,在自己电脑上可以通过 localhost:8080/xxx 来访问自 ...

  6. Python - 利用flask搭建一个共享服务器

    零.概述 我利用flask搭建了一个简易的共享服务器,分享给大家 一.python代码 import os import time from flask import Flask,render_tem ...

  7. 教程:动手用自己电脑搭建一个网站 (nat123 花生壳 动态域名 个人电脑做服务器)

    先ps一下..今晚试了N种方法,终于找到一个靠谱 免费 好用的方法,来改装自己电脑成为服务器,在外网也能通过域名访问了!!! 需要准备的东西: Tomcat:这个是web容器,其实有了这个就已经让电脑 ...

  8. 3分钟搭建一个网站?腾讯云Serverless开发体验

    作为一个开发者,应该都能理解一个网站从开发到上线,要经过很多繁琐的步骤. 编写代码,部署应用,部署数据库,申请域名,申请SSL证书,域名备案,到最终上线起码要几天时间. 作为一个不精通代码的业务玩家, ...

  9. [译]简单得不得了的教程-一步一步用 NODE.JS, EXPRESS, JADE, MONGODB 搭建一个网站

    原文: http://cwbuecheler.com/web/tutorials/2013/node-express-mongo/ 原文的源代码在此 太多的教程教你些一个Hello, World!了, ...

随机推荐

  1. angular : direative :comunication 指令之间的通讯

    在网络上可以找到多种指令之间的通讯 · $on,$emit,$boardcast (向上或向下冒泡) · 指令return的required (^)向上一个scope通讯,前提要先给scope一个na ...

  2. ASP.NET Core MVC上传、导入、导出知多少

    前言 本君已成夜猫子,本节我们来讲讲ASP.NET Core MVC中的上传,这两天才研究批量导入功能,本节顺便简单搞搞导入.导出,等博主弄妥当了再来和大家一并分享. .NET Core MVC上传 ...

  3. 每天一个linux命令30)--chgrp命令

    在Linux系统里,文件或目录的权限的掌控以拥有者及所属群组来管理.可以使用chgrp 指令取变更文件与目录所属群组,这种方式采用群组名称或群组识别码都可以. chgrp 命令就是change  gr ...

  4. 去掉Dedecms幻灯片的标题文字和绿色背景

    在操作dedecms站群中的站,因为看到首页的幻灯片Flash显示标题和文字,显得有点突兀,觉得应该去除dedecms 幻灯片默认的文字标题和背景,这样会感觉舒服些,下面教大家如何在模板当中去除ded ...

  5. 《Django By Example》第八章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:还有4章!还有4章全书就翻译完成了 ...

  6. canvas小球动画原理

    随着html5发展,canvas标签作为h5革命性的发展标志也越来越流行.canvas标签的强大之处,不仅在于它可以作为一个独立的画布,也可以利用canvas做一些动画而不用导入flash文件.同时, ...

  7. 香港多IP站群服务器-搭建多IP代理服务器、游戏加速服务器

    耀磊花楹qq82521463香港WK自营机房多IP服务器租用,多IP站群服务器,多IP多C段 站群服务器租用 耀磊数据拥有3万个自由香港IP以及独立AS号,是APNIC核心成员,机房通过BGP融合 多 ...

  8. html to pdf

    C++ Library to Convert HTML to PDF html2pdf PrinceXML 收费 CutePDF Ghostscript PDFDoc VisPDF PDFDoc Sc ...

  9. node.js爬虫爬取拉勾网职位信息

    简介 用node.js写了一个简单的小爬虫,用来爬取拉勾网上的招聘信息,共爬取了北京.上海.广州.深圳.杭州.西安.成都7个城市的数据,分别以前端.PHP.java.c++.python.Androi ...

  10. 关于Maven的安装及初步使用

    关于Maven的初步使用 1.  下载: 进入http://maven.apache.org/download.cgi下载  Maven 3.3.1 2.  将压缩包解压到自己的硬盘中,最好放在某个盘 ...