1.整体把握

(1)路飞学城 - RestAPI 前后端分离开发 Django
Vue.js - DRF DjangoRestFromwork - 线上商城的经验 (2)智能玩具 - RestAPI 前后端分离开发 Flask
FlaskWeb框架 - Sanic Python asyncio
WebSocket - 长连接
App开发 - Android + iOS
MongoDB - NoSQL
人工智能 - 技术应用
机器学习 - Gensim
自然语言处理 - NLP (3)自动化运维 - Django
运维 -> 自动化

2.框架对比

Django :
优点 - 大而全所有组件都是有组织内部开发高度定制化 教科书级别的框架
缺点 - 大到浪费资源,请求的时候需要的资源较高 Flask ;
优势 - 小而精,组件只有Session,第三方机构强烈支持Flask,非常多的三方组件 简单至极
缺陷 - 由于三方组件的关系 稳定性相对较差 Flask-Session Tornado :
优势 - 异步IO 非阻塞 原生WebSocket
缺陷 - 组件 == 关于异步的不好理解 Debug难上加难 Sanic :
优势 - 异步IO 非阻塞 原生WebSocket + 小而精,组件只有Session,第三方机构强烈支持Flask,非常多的三方组件
缺陷 - 复杂度 扩展知识:
QPS = 请求每秒钟的次数 QPS ==
时间片 cpu 工作一次的时间单位
py 假线程 - 1个核心
真线程 - 4个核心 - 四个线程

首先,我们进入虚拟环境,virtual代表组件env代表环境,注意下图的选择内容

进入下图,看一下选择的内容

进入settings.py中,进行处理

安装一下上图中的flask.

装完之后的内容,见下图

3.Flask简单启动

三行启动Flask
from flask import Flask
app = Flask(__name__)
app.run() 六行启动Flask Hello
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "hello"
app.run()

成功访问,见下图

我们就使用"干净的环境变量就可以了"

六行搞定Hello

4.Flask响应

    Response三贱客:
.HTTPResponse return "hello"
.render return render_template("login.html")
.redircet return redircet("/login")
Flask 封装
.send_file() return send_file("文件路径")
打开并返回文件内容 确定会在响应头中加入 Content-Type:文件格式 + Content-Length:文件大小(bytes)
.jsonify({k:v}) return jsonify({k:v})
返回一个客户端可以识别的json格式字符串 确定会在响应头中加入 Content-Type:application/json

send_file

上图是返回的是文本文件的内容.也就是三行启动flask

我们查看到生成的是下图这样的html

我们可以返回文本文件当然可以访问二进制文件,什么是二进制文件?图片,视频,音频等等

同样可以处理二进制文件,音频,图片,视频

下面,我们从网上照一张图片"煎蛋"

保存,下图的图片

复制到下图的pycharm中

重启代码:

我们再看一下路由:

可能,不代表所有的都会支持.

这个时候,我们再看一下请求:

这个时候,我们可以访问视频了.

出现多个get_file是因为数据接收不完,所以出现了这个现象.

通过上面的三次测试,我们确定了,

下面介绍一下jsonify

首先导入jsonify

小的测试示例

运行,看一下结果:

下面,我们对比一下json&&jsonify的用法内容

运行:

注意这个content-Type响应的结果是text/html;charset=utf-8   结果是字符串

注意这个content-Type响应的结果是application/json

返回上边的结果的意义.

下面我们朝向ajax方向思考,先下载一个jQuery

右键,链接另存为,得到的结果见下图:

下面,我们写一个页面,写一下

下面我们看一下能不能加载成功:

上图,我们可以看到,已经加载成功了.

我们也可以直接拿到这个静态文件,见下图

我们再放一张图片在静态文件里边:

我们不用重启,直接访问的结果,见下图:

上边的背景也是黑色,也是jsonify

下面我们学习ajax的简写版只需要四个参数:

现在,我们需要向某个地方发送请求:

运行:得到下面的错误  405(METHOD NOT ALLOWED)

百度405错误,因为没有见过:

http的8种请求方式:

我们理解的是后端没有支持,因此,我们需要在后端加上方法,具体看下图:

这个时候,我们再次启动,得到下面的结果:

下面我们再写一个p标签

返回的结果1:

修改下面的内容:

重启,返回的结果2:

我们再次换成jsonify

重启,再运行,这个时候返回的结果见下图:

如果,我们访问的是json,下图是:

json显示的效果可能会好一些,但是这里边,我们需要找到的是json

这个时候,我们根本就没有办法通过字符串找到对应的msg

如果,我们序列化成jsonify,看一下msg

通过中间的某种协议沟通

0代表成功,1代表失败

如果前端没有写到,我们可以在jsonify写一个空值.

前端,我们通过alert返回

重启项目:

这个时候,出现了弹窗:

我们需要将需要的结果进行返回,这就是后端要干的事情,前端需要显示出来.

.send_file()   return send_file("文件路径")
打开并返回文件内容 确定会在响应头中加入 Content-Type:文件格式 + Content-Length:文件大小(bytes)
.jsonify({k:v}) return jsonify({k:v})
返回一个客户端可以识别的json格式字符串 确定会在响应头中加入 Content-Type:application/json 扩展  RestAPI-请求响应为json-请求支持的协议为http 8种请求
GET POST PUT DELETE OPTIONS//head trace
查  增 改 删

对应的CBV---原生  RestAPI

class

def   post    增

def   delete    删

def   put      改

def   get    查

def   options  跨域请求

最后两个方法的作用,解决后端传递文件的不便利

jsonify解决json响应不成功的问题

注意,jsonify也可以修改头,Content-Type: laoayi/woaini

大前提,前端必须支持

5.Flask Request

    比较特殊
from flask import request #公共变量
# 公共变量 被覆盖?不会(第四天)
.request.args 获取URL中的数据
.request.form 获取FormData中的数据
.request.values 获取args+form 知道就可以了
.request.data 流 # 获取请求体中的原始数据
.request.json 字典 # 请求头中带有Content-Type:application/json 将请求体中的数据反序列化到json中 但是在data中依然存储这原始数据bytes .request.files 获取FormData中的文件数据 request.files.get("my_file")
request.files.save(默认提交的文件名) 记住:request.method

后端只能响应请求,所以先讲响应,再讲请求.

首先,我们导入request

我们看到源码中写的是公共变量:

运行:

访问根目录:

服务端成功,打印出GET

运行:

运行:

服务端得到下面的结果:

运行:前端返回66666

后端返回下图所示:

如何拿到,下图中的id=1    ???

运行,试一下前端的结果:

后端得到的结果:

request没有这个属性,我们可以打印一下args

运行:

上边符合字典的规则,我们可以通过get拿一下

顺便,因为重启太麻烦,我们可以配置一下那个自动重启

自动重启的配置方式一:

方式二:(注释掉上边的那个)

注意上边的访问参数:

上图是我们得到的结果

思考一下,能不能把字典进行序列化一下?

运行:

真的将结果序列化成字典了

再看一下类型

运行:

我们再通过转化成字典的方式,再拿值

运行:

得到的结果,成功拿到:

如果写成ages

报错:KeyError错误

从字典中取值的两种方式:索引取值,get方式取值,get取值可以默认是None,也可以设置默认值.索引取值的方式是keyerror

写一个form表单

运行:(将上边的s去掉)

输入123,点击"提交",结果报405的错误

这个时候,我们需要添加两种请求的方式:

运行:

这个时候,我们提交数据就不会报错了.

目前我们只支持两种请求:下面我们开始继续操作

测试一下是否有POST请求:

输入123,提交

得到下面的结果:

没有post

修改成下面的样子:

运行之后,输入345,点击"提交"

我们并没有得到任何数据:

还是没有数据

依然没有

得到上边的结果

通过上边,我们知道values优点特殊,下面我们在处理一下

运行:

访问下面的地址

提交之后得到的结果:

得到的结果:(服务端得到的结果:)

输入123,点击提交

这个时候,我们可以拿到123

将上边转化成字典

点击"提交"

点击"提交"

上边,我们得到的是"输入的内容4566"和链接中的键值

原来页面中的内容:

现在页面中的内容:

点击提交:

得到下面的结果:

也就是先序列化input里边的,再序列化action中的,同时后序列化的会覆盖先序列化的,

values.to_dict()  #知道有这东西就行,一般不用,又不代表用

专业的叫法叫做FormData数据

.Flask Request
比较特殊
from flask import request 公共变量
# 公共变量 被覆盖?
.request.args 获取URL中的数据
.request.form 获取FormData中的数据
.request.values 获取args+form 知道就可以了
.request.data 流 # 获取请求体中的原始数据
.request.json 字典 # 请求头中带有Content-Type:application/json 将请求体中的数据反序列化到json中 但是在data中依然存储这原始数据bytes .request.files 获取FormData中的文件数据 request.files.get("my_file")
request.files.save(默认提交的文件名) 记住:request.method 当前的请求方式

第四个和第五个,

第六,以后还会遇到

选择完之后:

点击提交:

这个时候,得到下面的结果

点击"提交"

拿到下图所示的结果:

依然,我们没有拿到任何结果:

我们改变一下请求的方式:

提交

enctype="multipart/form-data"  #代表formdata的升级版

现在得到的数据是序列化之后的数据

思考,我们现在序列化这个files有意义吗?

点击"提交"

无意义,我们就拿出key

点击“提交",

得到上图的结果:

得到上边的结果没有意义,但是存储起来就有意义了

运行:

点击"提交"

在同一目录下得到这个数据

注意,再修改一下,新版本一定要写名字.

点击"提交",

得到上边的结果

不能修改文件格式.(可以改,但是修改一般没有什么意义)

直接刷新:

这样就将图片保存到静态文件里边;

提交:

这样,我们就得到上边的结果.

6.Jinja2(爸爸flask用的)-template(儿子django用的)

    {{}} 引用 执行函数
{%%} 逻辑代码

在做之前,我们先找点数据

添加一个函数

创建一个index.html页面:

我们下面对模板做一个备注

第一次写可能不是这样的,可能是Template Folder

在上边,我们选择"Jinja2",这样就不显示黄色下划线了,这样操作之后,我们就支持Jinja2

包括在python中不显示下划线和在html中jinja2的语法

下面我们从python的函数中传递数据到html中.

注意,我们传递的是stu,上图中多了一个逗号

启动,我们看下我们的数据

显然,我要的不是这样的效果:

我们可以通过字典进行取值.

下面是三种方式取数据

运行:得到下面的结果

django中只支持  点

下面我们在传递一个列表数据

运行:

我们可以想办法将它遍历出来

这个位置有点重名,但是作用域不同.

运行:

如果每组数据换个行,只需要加一个p标签就可以了

这样就可以换行了.

如果不想循环怎么办?一个一个吧

依然是可以拿数据的

运行:

运行:得到下面的结果

jinja2功能多了一些

这个时候,我们得到上边的结果.

得到下图所示的结果:

在表格中加上边界:

运行:

得到下面的结果:

上边有一个性别错误,下面我们进行处理

下面进行扩展一下:

    {{}} 引用 执行函数
{%%} 逻辑代码 if for macro

对比django中的simple_tag

引用函数

在前端执行函数,传参

下面我们进行升级,让所有的页面都能用这个函数

修改成全局模板之后,我们不在需要传递函数

现在,我们直接调用就可以了

这个时候,每个页面都可以用了

jinja2中的macro语句,相当于def,也就是定义函数

除了定义函数,我们还需要执行函数

这个时候,我们得到上边的结果

这个时候,得到上边的结果

也就是上边的宏指令

上边这个有点鸡肋的感觉.

只有django是template    高度定制化的东西

其他flask和tornado和sanic都是原生的东西,也就是jinja2

7.Session   Flask中的Session  flask原生自带的Session,不是第三方组件中的Session

    from flask import session
app.secret_key = "序列化Session需要的字符串儿"
在视图函数中
session["key"] = "value"

我们通过request的源码找到session

点击进去,

上边的两行代码,特别的相似.

再创建一个login2页面:

上边我们进行了判断.

运行:

输入123

得到下面的界面:

很显然,上边不是我们需要的效果

运行:输入admin

提交之后,显示"错误"

我们使用正确的密码登录

得到 结果:

下面我们将输入的session,保存

点击登录,报下面的错误:

也就是说,在app里边设置一个secret_key

这个时候,我们再添加一行这样的信息.

再次运行:

输入密码,点击"登录"

这样,上边我们就登录成功了.

这样就代表我们我们session已经开启了.

我们设置一下,只要定向到index页面,我们就打印session["username"]里边的内容

再次运行:

点击"登录"

服务端也就打印出了这个内容.

session存放在哪个地方?内存中?不是,

这样我们就得到session的位置.存储在浏览器中.

session和cookie是什么,区别是什么?

通常我们解释的是session存放在服务端的键值对,cookie是存放在浏览器端的键值对.

在flask这里,我们在浏览器中,看到了session,三观改变了,我们看到的是序列化的session.

一切朝着最小化,精细化搞事情,朝着精简的方向搞事情.

flask连数据库都没有,为什么占用我服务端的资源存储客户端的没有用的资源,所以存储在客户端.想办法,将自己的状态自己保持,但是这个时候就不安全了.

我们是否能够拿到上边的资源在另一台机器上实现登录?答案是否定的.

session是有加密机制的.这里边存储的就是我们的数据

//eyJ1c2VybmFtZSI6IkFsZXhEU0IifQ.XK9VAg.JLrPbOZk5Urlxzh7mDimPFIE2Uo

//

这个时候,我们向这里边多添加几条数据,理论上会变长很多,下面看一下

再次运行:点击"登录"

//eyJ1c2VybmFtZSI6IkFsZXhEU0IifQ.XK9VAg.JLrPbOZk5Urlxzh7mDimPFIE2Uo

//.eJyrViotTi3KS8xNVbJScsxJrXAJdlLSgQsaYhU1wipqjCRaCwD6YRwn.XK9XlA.O10ASWENVes-Qtlep4vqZdHudhI

这个时候我们得到的结果只是长了一点点,再多也是只长一点点

也就是将一样的值进行了序列化了.所以我们看不出来了.

再次运行:

//eyJ1c2VybmFtZSI6IkFsZXhEU0IifQ.XK9VAg.JLrPbOZk5Urlxzh7mDimPFIE2Uo

//.eJyrViotTi3KS8xNVbJScsxJrXAJdlLSgQsaYhU1wipqjCRaCwD6YRwn.XK9XlA.O10ASWENVes-Qtlep4vqZdHudhI

//.eJyrViotTi3KS8xNVbJScsxJrXAJdlLSgQsaIkRjSs3MjSxiSs1NUpKRVBghqzA1TEzGUGGMrMLC0jwNqqIWAMSlJ7I.XK9Ycw.b4ls6NT-ebmqmxa1-LPhQgkpvNs

得到的结果是:session中一定存放的是key-value,注意安全只是相对的

也就是说加密和解密都需要上边我们设置的字符串.

app.secret_key="secret_key"

如果我们修改了这个字符串.

运行:

只是执行下面的页面得到的结果

这个时候session就无效了.

这里边携带了很多的信息,加密机制是个pass.

上边是一个装饰器

写这个装饰器的目的就是加上session

被装饰的函数一定在下面,

@classmethod  类方法装饰器

@property    属性装饰器

当然上边的存储字典是不行的,我们必须存储字符串

如果登陆成功,代表index函数中就有session了.

上边这种方式出不来数据,可能当时环境存在问题,再次调试的时候,可以得到相应的数据了

下边这种方式是可以出来数据的

alt+上  纵向选择

alt+enter  快速找包.

巨蟒python全栈开发flask1的更多相关文章

  1. 巨蟒python全栈开发linux之centos1

    1.linux服务器介绍 2.linux介绍 3.linux命令学习 linux默认有一个超级用户root,就是linux的皇帝 注意:我的用户名是s18,密码是centos 我们输入密码,点击解锁( ...

  2. 巨蟒python全栈开发-第20天 核能来袭-约束 异常处理 MD5 日志处理

    一.今日主要内容 1.类的约束(对下面人的代码进行限制;项目经理的必备技能,要想走的长远) (1)写一个父类,父类中的某个方法要抛出一个异常 NotImplementedError(重点) (2)抽象 ...

  3. 巨蟒python全栈开发linux之centos6

    1.nginx复习 .nginx是什么 nginx是支持反向代理,负载均衡,且可以实现web服务器的软件 在129服务器中查看,我们使用的是淘宝提供的tengine,也是一种nginx服务器 我们下载 ...

  4. 巨蟒python全栈开发linux之centos3

    1.作业讲解 (1)递归创建文件夹/tmp/oldboy/python/{alex,wusir,nvshen,xiaofeng} 下面中的路径没有必要换,在哪里创建都行,根目录下或者tmp目录下或者其 ...

  5. 巨蟒python全栈开发django5:组件&&CBV&FBV&&装饰器&&ORM增删改查

    内容回顾: 补充反向解析 Html:{% url ‘别名’ 参数 %} Views:reverse(‘别名’,args=(参数,)) 模板渲染 变量 {{ 变量名 }} 逻辑相关 {% %} 过滤器: ...

  6. 巨蟒python全栈开发-第11阶段 ansible_project2

    一个NB的网站: https://www.toolfk.com/ CDN:将用户的需求送到最近的节点:内容分发网络 有些是专门做CDN的工具 常用的markdown是需要知道的,短信有字数限制. we ...

  7. 巨蟒python全栈开发-第4天 列表&元组&range

    今日内容大纲 1. 什么是列表 定义: 能装对象的对象 在python中使用[]来描述列表, 内部元素用逗号隔开. 对数据类型没有要求 列表存在索引和切片. 和字符串是一样的. 2. 相关的增删改查操 ...

  8. 巨蟒python全栈开发-第13天 内置函数 匿名函数lambda

    一.今日内容总览 1.内置函数(1):并不是每一个内置函数都是那么常用 上菜:内置函数部分//思维导图:https://www.processon.com/view/link/5b4ee15be4b0 ...

  9. 巨蟒python全栈开发-第14天 内置函数2 递归 二分查找

    一.今日内容总览 1.内置函数补充 repr() 显示出字符串的官方表示形式 chr() arscii码中的字,转换成位置 ord() arscii码中的位置,转换成字2.递归 自己调用自己 两个口: ...

随机推荐

  1. 【转】Python——编码规范

    来自于 啄木鸟社区 Python Coding Rule --- hoxide 初译 dreamingk 校对发布 040724 --- xyb 重新排版 040915 --- ZoomQuiet M ...

  2. Django——静态文件配置

    本文目的 最近用django开发项目,发现django的静态文件(js,css和img等)配置比较麻烦,开发环境和生产环境的配置还不一样,这里记录一下,作为备忘.我当前使用的版本是django v1. ...

  3. 基于Vue开发的tab切换组件

    github地址:https://github.com/MengFangui/VueTabSwitch 1.index.html <!DOCTYPE html> <html lang ...

  4. Yii2.0 下的 load() 方法的使用

    一 问题 最近在使用 Yii2.0,遇到一个 bug:在 /models/OrderDetail.php add() 方法中调用 load() 方法加载数据,却加载不了. public functio ...

  5. MySQL 5.6数据导入报 GTID 相关错误

    从阿里云备份数据后还原到本地,用命令行 mysql -uroot -p --default-character-set=<character> -f <dbname> < ...

  6. Android Framework 分析---2消息机制Native层

    在Android的消息机制中.不仅提供了供Application 开发使用的java的消息循环.事实上java的机制终于还是靠native来实现的.在native不仅提供一套消息传递和处理的机制,还提 ...

  7. 调用getChildFragmentManager时出现的Bug

    异常: java.lang.IllegalStateException: Activity has been destroyed at android.support.v4.app.FragmentM ...

  8. kafka分布式搭建

    kafka分布式搭建 (192.168.230.129)master (192.168.230.130)slave1 (192.168.230.131)salve2 在master.slave1.sl ...

  9. 统计MSSQL数据库中所有表记录的数量

    SELECT a.name as '表名', b.rows as '记录数' FROM sysobjects AS aINNER JOIN sysindexes AS b ON a.id = b.id ...

  10. java中获取长链接的域名

    示例:长链接:https://www.baidu.com?a=1&b=2 域名:www.baidu.com static String getDomainUrl(String url) { S ...