对应原视频 第29集  补充flask(上) & 第30集  补充flask(下):

本篇概要:

P29

--flask框架的样子

--创建flask框架后直接运行就报错、测试、解决

--通过路径获取字符串参数:

--传入数字等其它类型的参数:

--如何返回一个html网页文件给用户?

P30

--传递普通变量:

--传递字典类型变量:

--表单提交:

--小结:

P28 数据可视化介绍

20201123

18:02

Flask框架。路由转发由Werkzeug完成,页面渲染由Jinja2完成。

P29  补充flask(上)

学一门编程语言,第一个写的程序一般就是hello world。但做的第一件事情并不是直接一上来就开始写程序,而是怎么样来搭建一个环境。

--flask框架的样子

在pycharm中快速新建一个具有flask框架的项目,就是让它给我们一些已经准备好的程序。

新建一个项目flask demo,类型选Flask。之前都是pure python。打开就看到有两个文件夹,打开看会发现还是空的,还有一个app.py的python文件。

这两个空文件夹会存放可能我们未来要用的一些文件。

static文件夹:存放js、css等文件,用来进行网页相关素材的提供。存放网页要用的素材的。

templates文件夹:模板。里面放的是一些html的网页文件,就是反馈回给用户想要访问的一些内容。

show in explorer:打开文件所在的位置。

debug模式:开启后,后台更改了,网页端刷新可以同步更改。调试用的,网页端访问有什么问题,会详细显示在网页上,这样就可以根据问题来修改。不开启debug模式的话,只会出现错误的类型,不会有具体的原因显示出来。

configurations:配置

--创建flask框架后直接运行就报错、测试、解决

我直接运行创建项目时自动生成的app.py程序,它报错了:

说是出现了无法进行转换的二进制数据。

我什么都没干,就运行默认生成的程序都会报错。

我不知道怎么解决,在顶部加了句防止中文乱码的:

# -*- coding = utf-8 -*-

但还是不行。

于是去搜索了解决方法,说是电脑的用户名是中文的缘故,改成英文的重启后就可以。我电脑的用户名确实是中文的,可能是因为这台电脑要充当服务器的缘故吧。

来源:

1、flask报错UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc1 in position 0: invalid start byte_林映青的博客-CSDN博客 https://blog.csdn.net/weixin_41704182/article/details/88979134

2、学习Flask遭遇UnicodeDecodeError: 'utf-8' codec can't decode - 简书 https://www.jianshu.com/p/2b4eec12a739?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes

修改电脑用户名来源:win10更改电脑用户名_懂视IT https://it.51dongshi.com/esgedfgsdhe.html

我要关闭去重启电脑了。19:36

20:07

重新打开,电脑用户名已经修改成英文的了,但是打开pycharm运行app.py这个文件,报的错还是一样的。改用户名还是解决不了。

我搜索词用的是:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc1 in position 2: invalid start byte

或者:flask app.py UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc1 in position 2: invalid start byte

或者python app.py UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc1 in position 2: invalid start byte

搜出来的看了很多,有关的就是上面来源的那两个链接了。不行,问题还是那样,又找了好久,但根本找不到这个问题的解答。我搜索能力很一般,可能有这个的回答,也可能没有专门针对这种情况的回答,结果倒是一样的一致,没有解决思路。

我又去搜了另外的一些python flask的教学视频,看了几个,都没有出现我这个问题的情况,都是直接运行人家的就出来了,在弹幕和评论中也没有这方面反馈。

我自己实在找不到,就去群里面问了这个问题有没有人会解决,一直期待有回答,但最终还是没有人回答。这个交流群最后也没有解救我于水深火热之中,因为我一直把这个群作为最后的稻草,不到不得已我是不会来问的。我真的毫无头绪,我觉得脑袋嗡嗡的,怎么想怎么查都找不到头绪找不到解决办法,也不懂为什么,原因是什么,还用了try catch异常捕获试着找问题源头在哪,也不成功。除了像老师那样用,没有讲的我是不懂的。

这个好像是引入的包或者模块什么的原因,好像是编码问题,但我不知道编码的概念,我不懂说实话,过程中用的utf-8,我就不太懂这是什么。我就知道是防止中文乱码的,怎么用就是按照老师那样写上去就行。我也这样在里面写了,完全没有用。我头都要炸了,stress,我感觉压力好大,我什么都不懂,我自己不会解决啊,也没有可以帮我答疑的人,也没有那么多钱参加课程这样就有答疑服务了,没有啊,所有的路都是堵塞的,我stress。这个解决不了,后面的就都无法进行下去了。why?what’s the reason?how to deal with it?can anyone help me?我处于崩溃边缘,我都想放弃了。

我围绕这个问题两个半小时,我看着一晚上就快过去了,我还是在这个问题上蒙圈,这种毫无出路的绝望的感觉,在这两个半小时满溢。因为我没有什么编程的知识背景,就连pycharm这个软件怎么用,我基本停留在老师有讲的部分,其它你叫我操作我不会。我连安装这个软件都弄了很久才成功的,因为我不会啊。我真的有太多不懂的了,太多太多,我好想自己懂多一点点啊,虽然现在都是小菜,基本知识基本操作,对小白来说可以难得要了命,是我水平太低了。

处于基本放弃的状态中,随缘吧,能解决就学,解决不了就放弃这个学习吧。然后不抱希望地又搜了一下,因为又想到一种搜索词。

搜索词:新建Flask项目时报错UnicodeDecodeError: Exception in thread Thread-2:

然后就出现了一条有搜索关键字眼的解答,我眼睛都放光了,感觉我好像又有希望了。

来源:pycharm创建Flask项目出现UnicodeDecodeError的解决方法_ruanxuan的博客-CSDN博客 https://blog.csdn.net/ruanxuan/article/details/108422506

看了搜索结果,就只有这一条相关的,我感觉自己又复活了,我好希望这条能解决我遇到的问题啊。按照它的方法,file—setting—file encodings,打开看到我的是这样的:

模糊记得之前遇到过问题,也打开过这个地方,当时增加了对global encoding的认识,就是里面选的会适用到全局,就是所有的都会适用它。project encoding就是这个项目用的,不会影响这个项目之外其它的运用。我好像有点感觉了,对这个有一点点自己还无法用文字来说清道明的理解了,就是对这两个(utf-8、gbk)有一点知道了,但自己还不会说。虽然我不知道gbk是什么,但是它们两个不一样,有冲突,原因应该包括这个。我现在要将它改成一致的:

希望能成功,真的!!!!

还是不行。

突然发现有一条里面是改计算机名的。

(改计算机名的步骤:flask常见报错:UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xd4 in position 0: invalid continuati_陈福国的博客-CSDN博客 https://blog.csdn.net/qq_45112637/article/details/108529404 )

我去查了计算机名,此电脑—右键—属性,看到我的计算机名是中文的,那么前面改的用户名是什么?我好晕,不知道这些干嘛的。那用户名我可以改回原来那样吗?我喜欢原来的那样,待会试试。现在保持英文。

现在把计算机名为英文的,重启:

ohmygod,onmygod,成功了,成功了,啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊~

好开心,在0:00这一刻,问题终于被解决了,今日的问题截止到今日,明天不用为这个问题烦扰和停止不前了。这期间我多期望看到上面这个内容啊,我快要被整疯了解决不了。前面也有气疯烦透的时候,感觉今天这个真的好不容易,都不是学习的范围内的,再简单我也搞不懂,再简单对我来说也是天大的难题。

好吧,我承认,遇到解决不了的问题都心态爆炸亮红灯,没有哪个难点容易点,都很难,都是疯魔状的亚历山大,stress~。

哦耶,这个不再是我的问题了。可以进入下一个问题的预备阶段了,虽然不是高兴的事,但解决了这个问题才有机会遇到下一个问题呀,这样想想,问题也是有等级的,我要向更高等级的问题迈进。

今天就是解决这个问题用的。明天再继续吧。另外补充一句,我已经将后面的全部看完了,对整体的概况有了模糊的认识,好像对具体操作会更有点帮助,写到那个代码块的时候,仿佛对它在未来运用后的成果有点模糊的联系,它的作用是什么,最终成果是怎样的,它起了哪一点作用,仿佛都有一点模糊的认识,只是说不出来。就是看完了,对将要学的东西理解更有帮助似的。不过今天就解决一个问题用完了,好在也解决了,明天可以继续了。0:21

20201124

15:25

127.0.0.1:本机的IP地址。

5000:端口,5000这个端口。通过这个端口就可以访问当前这个flask。

run():run方法,就是启动我们的服务器,就是我们的电脑,可以接受外界访问。它不停地监听5000这个端口有没有用户访问,有的话就返回相应的操作。不过这个是本地访问。

相应操作就是这里的代码:@app.route('/')

def hello_world():

return 'Hello World!'

route():路由解析

开启debug调试模式后,修改好了,还要保存一下,ctrl + s,然后在网页直接刷新就显示修改后的效果,不用每次修改都要关闭服务器再开启。保存一下就是把修改的内容上传到服务器,在网页刷新就可以显示出来了。

WSGI:Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI被开发出来以后,许多其它语言中也出现了类似接口。

(信息来源:wsgi - 搜狗百科 https://baike.sogou.com/v466274.htm?fromTitle=wsgi )

traceback:回溯

interactive:交互式的

plaintext:明文,明码文本,纯文本档案

arbitrary:任意的,随机的

introspection:内省,反省

dump:丢弃,推卸,垃圾场,废物堆,脏地方

--通过路径获取字符串参数:

route中的name是一个变量名。

定义的函数,想写一个加上用户名称的欢迎语。可以看到,函数中的name和route路由中的name并不通用。我们要在函数中对这个name进行定义。

这样就不报错了:# 通过访问路径,获取用户的字符串参数

@app.route('/user/')

def welcome(name):

return "你好,%s" % name

这什么意思呢?

这意思就是说,当用户访问的时候,它的网址/user/后边有这样的内容,我就把当作一个名字,当作函数welcome(name)中name的值,传到def welcome(name)这个函数里来。传进来之后,因为name是函数中定义的名字,那么我就可以把name当作一个变量来直接使用了。

保存运行一下:

回车,结果:

我就是很奇怪,我为什么要在这里写字呢。现在这个就是为了学而学,我自己想不到它的应用,老师也没有讲解它的应用场景。现在就是为了学这个而学这个,没意思。如果以后有用到它的应用,现在告诉一下大概讲解一下,也不至于现在很无趣地记住。等到未知的未来可能才会发现它的用处,让人在这段时间内不知道学这个点干嘛。你知道的话,说一下不行吗?就说几句不行吗?你以后就知道它的用处了!!!!这种话简直让人倒胃口,你现在知道就是不肯说,我现在不知道,非要等谁也说不准的以后,你真是来搞笑的。这不是对老师说的,是我对以前的那些时间说的,我只是每次想起那些为应试浪费掉的人生,就恼火!浪费了之后才知道才意识到才明白,但是时间是回不去的。我为以前浪费掉的生命感到非常惋惜,我好讨厌应试教育。

好,继续。老师的教程只有一丢丢那种我想不到为什么要学的地方,几乎都是以实际运用为基础的,也有很多现实运用的讲解。我只是因为太讨厌应试教育了,所以导致嗅到一点应试的味道,也会比较敏感,马上激起情绪。

如果想拿到指定位置的内容,可以杠/,用尖角号,里边定义一下这个内容。定义多个也可以,记得函数中也要对应多个参数就可以了,它会自动匹配到函数的变量上。# 获取多个字符串参数

@app.route('/user//')

def welcome(name, data):

return "你好,%s,%s" % (name, data)

结果:

--传入数字等其它类型的参数:

可以通过字符串传进来,然后转型也可以。

也可以直接拿数字:# 通过访问路径,获取用户的整型参数。   此外还有float类型。

@app.route('/user/')

def welcome2(id):

return "你好,第%d号的会员" % id

表示把我输入的内容当作一个整型来看,id是变量。

此外,还有一个是传入float类型,浮点数,可以接受小数。

路由路径不能重复,用户只能通过唯一的路径来访问特定的函数。如果重复了,访问了相同的路径,就不知道该调用哪个函数了,就会出错。

但是可以从访问的一个函数跳到另一个函数。redirect,这里不做介绍。

有人说这也不像一个网站呀,这也太简陋了。网站应该像访问一整个HTML文件才对呀。

其实html也是文字,它的源代码,它的图片,其实也都是文字。

那我们要自己写html文件吗?不用,通过Jinja2来帮我们完成。

flask里有两个重要的东西,Werkzeug和 Jinja2。

@app.route('/user/')

def welcome2(id):

上面这两句话是由Werkzeug来完成的,它来判断到底哪一个路径来执行哪一个函数。

return "你好,第%d号的会员" % id

返回是由Jinja2来完成的。Jinja在日语里是神社的意思。弹幕:直接返回静态文件的html。

这个Jinja2怎么用呢?我也没看见有这些包呀?

其实在创建的时候,就自动带进来了Flask,Werkzeug,Jinja2这三个包,在file-setting解释器里可以看到。

在程序里,我们不是直接使用Jinja2,而是引进render_template这个模块,Jinja2已经包含在这个模块里了。它帮助我们把我们想要的html文件给展示出来。

from flask import Flask, render_template

render:渲染

template:模板

--如何返回一个html网页文件给用户?

首先我们先新建一个html文件。注意,只能在templates这个文件夹里新建,在其它地方新建,render_template识别不到:

弹幕提醒:app.py必须跟templates文件夹在同一级。

现在在里面写几个字,虽然是很简单的网页,但也是个网页:

把这个网页显示给用户:# 返回给用户渲染后的网页文件。

@app.route('/')

def index2():

return render_template("index.html")

当用户访问杠/的时候,就调用def index2():这么一个函数,然后返回一个渲染模板template_rendered执行的这个代码(index.html),就是帮我们把这个index.html文件给渲染出来。

渲染不就是发出来吗?诶不止。现在你看到的是一个html,其实它在里边做了一些工作,就是帮我们检查一下这个index.html里边有没有什么它Jinja2能够识别的一些符号。如果有一些符号呢,就把它转成html。有哪些符号,稍后再看。就这么一句话(return render_template("index.html")),实现了把网页文件转给用户的这么一个过程。

我们看到,其实我们真正要学的就是两步,定义你的路径,把你的网页准备好,返回给用户。18:10

P30  补充flask(下)

22:10接下来我们再补充一些内容。在后边要使用这样的一个过程的时候,这个网页上不仅仅是要显示已经准备好的东西,有的时候可能我们要显示一些我们从数据库里查出来的东西,那么这个怎么样子来放进去呢?

因为这一个网站是静态的网页,静态的网页它没有什么动态的内容,只能是把写死的显示出来。

我现在希望能让它里边动态的显示一些,我们能够在数据库也好在后台操作这些内容。怎么办呢?这个时候我们就需要向页面传递一些变量。

那怎么样来传变量呢?就相当于让页面上像刚才这个地方欢迎光临欢迎谁光临啊,能不能在这里边有动态的名字。刚才我们说在上边已经可以通过这个地方的ID来进行。来一个判断直接显示在这里了,那这个东西我怎么样添到网页里呢?刚才我是直接显示文字,我可以显示出来。

现在这人家可是个网页,我要把我从程序里拿到东西塞进去。怎么办呢?这就是我们想跟大家说的这个渲染的作用啊,就是帮助你把一些变量塞进去。

那么怎么塞呢?我们在这给大家一次看三个我们常用的变量。

--传递普通变量:

比如说我们在这给大家显示一个时间,我们一直没有讲过时间。先引入一个包datetime可以来显示时间:

这里边date就是这个日期,日期里边还有很多,有最大日期,最小日期等。除了日期大家可以看到它里边也有time,也有具体的时间,你自己可以下去自己试一试。import datetime

# 向页面传递一个变量。

@app.route('/')

def index2():

date = datetime.date.today()    # 普通变量

return render_template("index.html", var=date)

variable:可变的。变量。

Assertion:断言,声明,认定。

var就是变量的意思。这个var就用在我们这个页面上,在页面上显示出来。所以要把它塞到页面里边去,页面就通过这个var,就能拿到你塞的内容了,就会在页面上显示出来了。怎么放?

现在重新再回到这个页面上来,在欢迎光临这个地方:如果你要想要输出服务器端传过来的内容,注意这地方用一个符号叫做大括号,就是一个大括号外边又套了个大括号,用这种方式来直接写今天的时间是多少。

其它地方都是我们的这个语句,就这两个大括号嵌套起来,里边包含的内容就是我们服务器里边传过来的东西。

比如说我们这几个话,大家看它直接变色了,表示它不是html语句。它是我们这个Jinja这样子的一个模板,它去解析的它,通过这样的两个大括号来解析我们当前的这样的一个变量名。

我们再看一眼,其实就是通过我们这个渲染网页(index.html)的时候,给它塞进去一个变量(var),这变量的内容(date,time)就是我们这儿写的一个内容(date = datetime.date.today()  time = datetime.time.hour)。这个内容在网页上怎么显示?两个大括号嵌套里边写上变量名{{ var }},我们现在执行一下,我们刷新。

结果:

如果你要看源代码,你点右键看源代码:

你看这个地方,它其实就是普通的字符串,并没有什么样的一些新的符号。而你刚才在html页面上写的大括号这个东西,是在刚才我们在后台执行这个叫render_template,它在返回给你html的时候,它把html页面上这个var的这个位置给你替换了,替换成了我们当前的这样的一个时间。

所以你在最后的这个浏览器里是不会看到我们的源代码的,你看到的就是渲染以后的这样一个输出结果。这个大家应该能理解了。所以想给大家说的是特殊的一种表达方式,就是两个大括号嵌套,就可以在这里边获取到我们服务器端,或者说在渲染的时候传递进来的这样的一些变量名了。

好,这就是第一个变量类型,这就是普通变量,或者叫一般变量,都可以。

那常用的变量大家也知道,我们平常生活中还有两个变量,我们在前面讲数据结构的时候也说过,一个是列表类型,一个是这个我们叫做字典类型。

--传递列表类型变量:# 向页面传递一些变量。

@app.route('/')

def index2():

date = datetime.date.today()    # 普通变量

name = ["小张", "小王", "小赵"]   # 列表类型

return render_template("index.html", var=date, list=name)如果我现在就想两个同时传怎么办呢?还是一样的,在后面追加就行了。那同学说这个变量名怎么起啊?都行,你这个叫name也行。它这个变量和后边的变量名是没冲突的。

这个是list这是name,前者(list)是我们在网页上渲染的时候用的,后边这个(name)就是我们在程序这个地方定义的,这一定要分得清。弹幕说:老师有一个不太好的习惯,变量名的命名和属性名重复。我不了解属性名,但也可以给我一个思路。

放到html里,用循环遍历出来单独显示:

Title

今天是{{ var }}欢迎光临!

今天值班的有:

{% for data in list %}

{{ data }}

{% endfor %}

结果:

在html中是换行的意思。

控制语句有用这样一个形式:{% for data in list %}。在%之间写。这个形式表示for循环的开始。

控制语句结束要写上结束的语句:{% endfor %}。中间不要有空格。这个形式表示for循环的结束。

它不是纯的python语句,它是我们这Jinja这样的一个模板,它去解析的时候的一个格式,所以它必须这么写。注意这没有冒号啊,这是注意的一点。

html注释的形式是:

打印里面的内容,和前面一样,用两个大括号括起来:{{ data }}

用大括号和百分号括起来的是控制结构。除了for循环,还有if,就这两个,没有太多。

不用for循环,直接写{{ list }},会直接打印出来,是这样子的:

当然你想让它有一个列表的形式的话,注意{{ data }}这个地方你不能在里边写任何的HTML代码,这里边只能写变量名。你写html你可以在这儿写:

Title

今天是{{ var }}欢迎光临!

今天值班的有:

{% for data in list %}

{{ data }}

{% endfor %}

结果:

没有进行过这个网站编写的同学可能看这儿会有点晕。解释一下,在这地方用大括号和百分号括起来是控制结构,控制结构的意思就是控制下边HTML语言渲染的时候,到底显示多少或者显示成什么样子,那么除了for循环,还有if,只有这些没有太多,它仅仅是一个符号的解析而已,所以它不是python语言啊,它仅仅是一种特定的这种符号解释。当然还有if的这地方,大家有兴趣可以再去了解。

我们通过这个方式其实主要想大家理解的就是怎么样在网页上来用这个for循环来进行相关的这样一个列表的打印。这就是我们这个例子想要介绍的。

--传递字典类型变量:

那么除了列表以外的话,还有个叫字典。怎么将字典传进去?这样传:# 向页面传递一些变量。

@app.route('/')

def index2():

date = datetime.date.today()                 # 普通变量

name = ["小张", "小王", "小赵"]                # 列表类型

task = {"任务": "打扫卫生", "时间": "3小时"}    # 字典类型

return render_template("index.html", var=date, list=name, task=task)

上面这个步骤就是将字典类型的变量传进去。

传进去之后,那怎么打印呢?回到html文件上来:这个例子想让大家了解的,不但是怎么样做任务,还想让大家了解一下,怎样子来进行这个表格的打印,因为后边我们会有用到,所以在这给大家介绍一下。了解以下这个如何在页面打印表格,这是HTML的基本功,但是怎么样跟我们的这个程序来混着用,这个是一个问题。以及如何迭代。

好,我们先来测试一下:

任务:

测试1 测试2
测试3 测试4
测试5 测试6

结果:

表格是:

每一行是:

每一列是:

多来几行几列就是多几个tr td,复制过来。

弹幕:table+table键,tr+table键,可以自动补全,或者table>tr*3>td*2。前面的试了可以,后面的那一串不行。

表格边界线是:border=

加框的地方是:

加了之后的样子:

大家看就这么一个最基本的表格,虽然长得有点丑啊。

回到我们的字典上来。

之前我们学过,一个是key,一个是value,它可以用这种方式来同时拿出key value,打印在这个地方,我们可以得到一个迭代器啊比如说task.items,就跟我们之前那个enumeric一样,在这里它叫items。通过这种方式就能直接把我们当前的这样的一个字典给拿出来。

用了items,这个字典它变成什么样子了?它其实变成这个样子了:

[(key,value),(key,value),(key,value)]

变成了列表形式,里面是一个一个的元组。items把这个字典变成一个列表形式了。

所以这个地方所谓的迭代器的意思就是说,它帮你把这个字典给你转化成了这样一种格式的一个列表。

Title

今天是{{ var }}欢迎光临!

今天值班的有:

{% for data in list %}

{{ data }}

{% endfor %}

任务:

{% for key,value in task.items %}

{{key}}{{value}}

{% endfor %}

结果:

因为items是一个方法,items这里少了一个括号,加上:items()

结果:我们这个例子就讲到这儿,回头我们再看一下,大家想一想这个流程其实比较简单,容易理解,但是想要真正的把它用起来,可能还得练习一下。

普通的变量直接赋值,列表变量直接赋值,字典类型传递,把它们连起来,直接赋值。这是完全一样的。

不一样的点就在于说想要单独打印就是直接打印(普通变量)。想要进行for循环,在列表上是好使的。想要对于字典进行循环,想要拿到里边的每一个键值对,可以使用这个items这样的一个方法,把它调用出来,分别拿到key和value操作就可以了。这总结到这里。

0:49

--表单提交:

20201125

14:27

表单提交涉及的页面至少得有两个html页面加上一个程序。什么意思啊?就是你首先得有一个填表单的一个界面,然后再来一个我们进行一个结果页的显示,就是提交以后到这显示成什么样子。

所以在这里边我们表单提交这个过程啊,给大家先写一个基本的页,就是你要访问一个基本页,所以在这里边还是艾特app点route。那这基本页叫什么呢?

比如说我们现在来个test,做一个叫register注册:# 表单提交

@app.route('/test/register')

def register():

return render_template("test/register.html")

注意,route里边的test和render里边的test是不一样的,上面的是指访问的路径,访问这个网页的路径。下面的test是指test这个文件夹,是指文件路径,这个文件夹在templates文件夹里的,因为render template只能渲染在templates文件夹下的文件,可以在templates文件夹里新建文件夹是没问题的。在下面就要指明在templates文件夹下的哪个新建的文件夹里。这里两个test的概念是不一样的。

render template不会自动帮你新建test文件夹和register的html文件的,所以自己要新建好,如下:

在templates文件夹下新建一个test文件夹,专门用来做测试用的,把测试的文件统一放在里面,免得和项目的文件混合了。以后自己调试每一步看行不行的时候,也可以按照这样的思路来做。

接着在html里写个表单就行:

我们就在这个界面里边写一个基本的这样的一个注册的一个内容,或者说写一个表单就行了。那写一个什么表单大家也知道,就是form放表单。这form表单里边一般有一个action,这个到底要提交一个什么动作,就是你要访问页面。哪一个页面啊?还有个叫method,那我们说表单一般都用post,也就是当你要进行搜索和登录的时候,把你的这个用户名密码加密一下这个意思。那这样的一个路径是什么呢?这路径其实你比如说我们现在比较简单,你就可以写死。那比如说action="http://localhost:5000",但后边其实这个路径是我们动态生成的,但是我在这就直接先写了哈。比如说在这我写个什么访问路径啊,比如说叫result,就是action=http://localhost:5000/result,说我想要结果啊,我想一个什么结果,就是登录注册以后的结果。

那么在这里边这form表单里边我们加几个内容:

姓名:

年龄:

性别:

地址:

在这个text里边我们直接写个name,这name有什么用啊?这个name是为了我们后边这个打印显示的时候和后台处理的时候用。一般情况下会建议大家用英文,但是我在这为了让大家直观一点,我写中文了哈。

好,就这么一个表单,那表单必须得有一个提交按钮,对不对?所以的话还得写一个按钮,这按钮的话大家也知道哈,就是一个input type=” submit”提交。当然这个里边的这个值value,比如说就叫提交。这个内容其实现在就可以显示出来了,通过这个网页路径我们就可以看到这个表单,我们可以先看一下:

写了这些内容之后,点提交,这个时候它访问的路径又来了。注意,这个表单访问的路径在哪呢?在这儿action=http://localhost:5000/result,它要访问的是杠result,也就是说你现在这个表单想要能让后台解析到,我们还得有一个这个result这样的一个路径解析的过程:@app.route('/result')

def register():

return render_template("test/result.html")

result.html这个文件先什么都不写就写个result,看一下行不行:

填写表单后,点提交:

结果:

说是覆盖了一个现存的函数:register。因为上面的定义/result路径的时候,函数名还是register()没有改,和上面重复了。现在改回来:@app.route('/result')

def result():

return render_template("test/result.html")

再次点提交。结果:大家发现什么问题?method not allowed,它说这个这个method不允许你现在这个request的这个请求。

诶你说这不是访问result吗?我这不是result吗?它为什么不允许访问呢?

哎这就是我们想说的,咱们默认的话,刚才大家没有选择的时候,它默认是get的方式来请求的。但你刚才这个请求是一个表单提交,是一个post的请求来的。

那么你在没有在这直接说明你可以接收post请求的时候,就会出现这样的一个错误,叫做这个方法不允许被访问。

那你说那我怎么让它可以允许一个表单的请求呢?在这后面加上逗号method:# 接收表单提交的路由,必须指定methods为post。

@app.route('/result', methods=["POST", "GET"])

def result():

return render_template("test/result.html")大家看到在这地方你后边可以加一个列表,你可以既是post的,也可以同时接受get的,你就在这里边写上这两个,你说我只允许post的,你就只写一个就行了。当你不写任何东西的时候,它默认的意思就是说只写一个get。

这个就是给大家说明的一个情况。想要进行表单提交的时候,接收端必须得有一个method接收这个表单提交的。就需要指定methods为post。

好,那这次我们再来试一下,我们这次再回到刚才的表单再提交一次:

诶大家看这次就可以了,这个result就显示出来了。

好,那么我们想说的是光显示不行啊,我们表单提交就是为了拿到我们用户输的内容的呀。

那你显示完了之后,我们怎么样拿到内容呢?难道还要在这写变量、写参数吗?

不用啊,这一次你会发现它里边有一些另外一些对象可以帮我们做这件事情,叫什么呢?叫request,它有个叫做request的请求的一个对象。在哪里呢?也在这个flask里边帮我们封装好了,我们逗号在上边,把它给引入进来:

from flask import Flask, render_template, request

大家看到request这条请求,它里边把我们现在用户端的相关的表单信息等等,要封装好了传给我们,我们直接在里边拿就行了。那怎么拿呢?@app.route('/result', methods=["POST", "GET"])

def result():

if request.method == "POST":

result = request.form大家可以在这儿用一下,比如说我们先判断一下,如果我们现在这个request这里边的一个方法叫method,它等于我们现在的这个post,也就是说我们是post过来的,它是知道的。如果是这种情况呢,我们就给它一个这个具体的一个做法,就是返回我们当前这个表单里边所有的内容。那怎么样获取到所有的内容?比如说我们现在定一个result这样的一个变量,它里边就存储了我们表单里边所有的内容,可以通过request这个对象点form,大家一会儿可以注意,这个form它就直接把我们那里边的所有的内容当作一个字典。大家想想是不是一个字典啊?

姓名:

年龄:

性别:

地址:

想想这个注册的这个过程,你姓名填了什么,年龄填了什么,性别填了什么,这是不是就是一个字典?

它其实就是把我们当前的这个表单里边的东西形成一个字典,叫做form这个表单传给我们这个result。

这result里边就是我们填好的那个字典。那字典就涉及到有键有值的。键是什么?注意,我们在这里边这个键就是我们这个name。

为什么我刚才给你说这个一般用英文比较好呢?就是因为这个一般都是键的名字,你在进行遍历或者显示的时候都方便一些。所以在这个地方type="text"这是值,就是你输入的内容。

所以在这种情况下,你拿到了之后,比如说现在我们不做什么操作,直接就把它传出去就行了:@app.route('/result', methods=["POST", "GET"])

def result():

if request.method == "POST":

result = request.form

return render_template("test/result.html", result=result)

那同学说如果不是post呢?那就是说明是get嘛,那你可以在这儿写else,你干别的,就返回一个别的网页也行。我在这不做过多的一个展示了。

我们只在这说,如果它是post的,我们可以在页面上拿到表单里的所有内容,就这么一个过程。

好,我保存一下,我们回到我们的这个结果页。结果页就是这个result.html这个页面上。

那这个页面上大家也知道是吧?我们需要做的就是把那个遍历出来:

Title

{% for key,value in result.items() %}

{{key}}{{value}}

{% endfor %}

当然这个键值的话,你可能这个结构跟刚才我们那个不太一样。对不对,一个是我们这个内容,一个是那个什么,你可以改一下,比如说我们这个是th:

{{key}}{{value}}

相当于是前面有一个标题,后边有一个内容,这样的话看起来更明显一点。

好,我们再来运行一下,重新填写提交:

大家看出来结果了,前面这个就是我们的键,这个键就是刚才我说的来自于你输入的那个input里边的name后边就是值。

--小结:

所以通过这个例子想给大家简单介绍一下,就是说我们如果一个表单的提交,是可以通过这样的一个路径@app.route('/test/register'),来直接跳转到我们的注册。那么获取这个表单的这个页面先把它准备好(register.html)。准备好的时候,这个就是你接下来要进行这个form表单里边的键的名字:name="姓名",name="年龄", name="性别",name="地址"。然后这个地方

,要写的就是你要申请的那个,我们说叫这个result这样一个函数(def result():)请求的一个路径,是这个路径(@app.route('/result',)。有了这个路径之后呢一定要在这个地方声明为post,它才能接收到post,form表单里边(request.form)声明了我们对应的这样的一个内容。所以在这个地方(return render_template("test/result.html", result=result)),就可以直接来进行页面结果的一个打印输出。输出到这里边(result.html),我们就直接通过这样的一个字典的遍历就可以了。

好,那最后再补充一个什么内容呢?这个地方:

大家可以看到这个地方你总不能这样写死吧,因为你这样写死之后呢我们可以看一下源码:

大家看这地方写的就是这样的一个路径了。但是等到真正我们发布网站的时候,你不可能是这个localhost对不对?它应该是你的域名或者是你的IP地址。

所以这个地方怎么样让它动态地获得到我们当前的这样的一个网址啊,这个地方有一个东西叫反向路由。

所以在这个地方我们通过我们这个路径把它给它封装一下:

这个不是说在我们这个Jinja里用,在我们那边也可以用。它是可以直接通过我们后边给它一个字符串,来帮我们动态的生成它现在真实的这样一个路径,比如说现在它这是要进行result的一个访问。

action="{{ url_for('result') }}"注意,这没有杠,这表示的是说直接帮我们找到特定的这样的一个路由的位置。其实是在网页上帮我们渲染生成了一个我们当前要访问的这样一个路径。

那么当前呢因为你是本地的,就是一个杠/,所以这一句话action="{{ url_for('result') }}"写完了之后呢,就是一个/result的意思。

所以我们现在不用写我们前面那一大串,刷新再看一下源码:

诶大家看这次我们这没有写什么杠啊,写的是url_for什么什么,它其实是动态的帮我们得到当前的网址的根路径,然后帮我们来填充一下当前的。这地方(url_for('result'))你只需要写的是什么,这地方你只要写你对应路由的名字就行了。所以在这个地方想跟大家说的是,它自动生成了一个杠result这么一个过程,这就是想给大家说的。在刚才那个表单提交的时候,不要写死你的http的这个地址,因为你可能换端口,可能换域名,而用url_for()会动态的帮你找到你所想要找到那个路由的路径。好,关于我们这个整个的一个flask,我们本次这个项目用到的就给大家介绍到这。因为整个flask其实还涉及到更多的内容啊,比如说你可能还要进行相关的这个表单配置啊,还有就是cookie呀等等,还有很多这样的一些具体的一些安全校验啊等等。你都是可以再继续自己学习的。建议大家也可以上网上搜一搜关于flask教程等等的内容,深入学习一下。那么上述内容对于我们做本次的项目就已经足够了。好,关于flask的这个内容我们就介绍到这里。

17:02

python快速注释html5_P29-30《Python爬虫技术5天速成…》学习过程笔记16(超详细记录)...相关推荐

  1. [B站视频]Python爬虫技术5天速成

    [B站视频]Python爬虫技术5天速成 课程介绍 1.Python基础概述 课堂作业1:IF语句实现石头剪子布 课堂作业2:用For和While循环打印九九乘法表 字符串常见操作(只介绍部分常用到的 ...

  2. 【Python爬虫实例学习篇】——5、【超详细记录】从爬取微博评论数据(免登陆)到生成词云

    [Python爬虫实例学习篇]--5.[超详细记录]从爬取微博评论数据(免登陆)到生成词云 个人博客地址:ht/tps://www.asyu17.cn/ 精彩部分提醒: (1)微博评论页详情链接为一个 ...

  3. python快速编程入门教程-python从入门到精通之30天快速学python视频教程

    python从入门到精通之30天快速学python视频教程 课程目录: python入门教程-1-Python编程语言历史及特性.mkv python入门教程-2-Python编程语言初接触.mkv ...

  4. python快速注释html5_python注释代码块

    atom python怎么注释代码块 script插件 是运行代码时使用,安装成功后,可以打开.py文件,快捷键ctrl+shift +b 运行python代码. 插件升级: 插件的初始安装可以使用a ...

  5. python基础笔记,超详细,包含面向对象基础,爬虫实战【持续更新中...】

    前言: 本笔记中的函数和方法同义,面向python3 本笔记部分概念及代码由newbing搜集整理得出 本笔记适合有一定其他编程语言基础的同学,因为笔记中省略了部分基础概念(比如整型,浮点型等基本数据 ...

  6. python快速编程入门例题-Python快速编程入门,打牢基础必须知道的11个知识点 !...

    Python被誉为全世界高效的编程语言,同时也被称作是"胶水语言",那它为何能如此受欢迎,下面我们就来说说Python入门学习的必备11个知识点,也就是它为何能够如此受欢迎的原因. ...

  7. Mongdb篇三。 用Python代码实现Mongdb数据库的增删查改、集合管道示例,超详细,全部用实例print大法演示功能通俗易懂。学pymongo库看一篇就够

    ⭐ 简介:大家好,我是zy阿二,我是一名对知识充满渴望的自由职业者. ☘️ 最近我沉溺于Python的学习中.你所看到的是我的学习笔记. ❤️ 如果对你有帮助,请关注我,让我们共同进步.有不足之处请留 ...

  8. Win10基于python,spleeter 人声提取工具安装和使用(全网最全,超详细)

    Win10基于python,spleeter 音频分轨工具安装和使用(全网最全,超详细) 小声BB(不想看可直接跳到正片) 碎碎念(写给小白) 正片开始 说明 总体的框架 详细步骤 1.安装pytho ...

  9. Python编程从入门到实践笔记(超详细的精华讲解+内有2021最新版本代码)

    编程环境的安装请见我个人博客https://tianjuewudi.gitee.io/的另两篇文章<Pycharm安装方法>及<Pycharm配置和使用教程>,下面以你能正常使 ...

最新文章

  1. 最小生成树算法MST_kruskal算法
  2. 一体化市场谋定国际品牌贸易 对话国际农民丰收节贸易会
  3. 数据结构与算法09 之图
  4. NAGIOS安装指南
  5. 来,看看你的单片机程序有多大!
  6. 我的世界python俄罗斯方块手机版下载_欢乐俄罗斯方块
  7. 苹果Apple Watch样机Mockups素材,你用过吗?
  8. 1003 我要通过! (20 分)—PAT (Basic Level) Practice (中文)
  9. 02. Win32 API简介
  10. ASCII码 编码对照表
  11. Android计分器课程设计,课程设计题八:篮球比赛计分器
  12. Python函数的返回值
  13. (附源码)spring boot小型仪器公司生产管理系统 毕业设计 031853
  14. 15种微信小程序运营推广方法
  15. 鸿蒙 林蒙 秦羽,从主神归来的主角们
  16. python你已经是个成熟的软件了_支付宝改自己还花呗表情包_你已经是个成熟的软件系列表情包大全_游戏吧...
  17. Java去掉字符串首尾的““
  18. python rgb转换为gray
  19. sdkd2019.3.20训练题目
  20. Linux系统概念复习

热门文章

  1. pythoniter雪峰_python学习(廖雪峰的官方网站)
  2. mos高压侧自举升压电路
  3. 常用的容器监控工具——Google的cAdvisor
  4. 毕业设计-基于深度学习的舰船目标检测技术
  5. Java核心技术----类的高级特效
  6. 2021-2027全球与中国手工玻璃制品市场现状及未来发展趋势
  7. matlab灰度归一化,[转载]matlab图像处理为什么要归一化和如何归一化?
  8. 笔记 GWAS 操作流程6-2:手动计算GWAS分析中的GLM和Logistic模型
  9. Siamese network
  10. 计算机应用实践教学体系,高职计算机应用技术专业实践教学体系构建-2019年精选文档...