Python Web开发—Flask快速建站—Flask概述、路由详解、Jinja2模板、SQLAlchemy、WTFor
时间:2023-08-04 05:03:01 | 来源:网站运营
时间:2023-08-04 05:03:01 来源:网站运营
Python Web开发—Flask快速建站—Flask概述、路由详解、Jinja2模板、SQLAlchemy、WTForm表点:介绍了Django框架进阶(Python Web开发—Django框架进阶—Django Admin站点管理、Admin站点简介、Admin站点配置与登录、Admin的使用、Admin站点的定制),目前在各大技术类网站(如github、stackoverflow)中讨论和询问度都排在前面的Python web框架是Django和Flask,接下来将学习Flask简介、Flask安装、Flask实现第一行代码、一般路由、带参数的路由、HTTP访问方式、生成URL、初识Jinja2、Jinja2基础语法、控制结构、过滤器、模板继承和SQLAlchemy安装、SQLAlchemy的初使用、使用SQLAlchemy进行数据库操作、表单定义、模板编写、接收表单数据、表单验证。
Ø Flask简介Flask是由Armin Ronacher使用Python编写完成的,它是一个轻量级的 Web 框架,其中使用的WSGI(详见第6.节“请求与响应”)工具箱是Werkzeug,模板引擎是Jinja2。Flask简点易学,自带开发服务器、集成点元测试、debugger,而且建站速度非常快。
Werkzeug是Python的WSGI规范实用函数库,基于BSD协议,在开发过程中使用十分广泛。主要有以下一些功能特性:
HTTP头解析与封装
易于使用的request和response对象
基于浏览器的交互式JavaScript调试器
与WSGI 1.0规范100%兼容
支持Unicode
支持基本的会话管理及签名Cookie
支持URI和IRI的Unicode使用工具
内置支持兼容各种浏览器和WSGI服务器的实用工具
集成URL请求路由系统
Jinja2是基于Python的模板引擎,应用非常广泛,就如同PHP中的Smarty,J2EE当中的Freemarker和velocity,如果大家对以上两者有所了解,理解起来会相对容易。Jinja2主要有以下特性:
具有集成的沙箱执行环境
具有强大的HTML自动转义系统,有效阻止跨站脚本攻击
执行效率高效
编译模式可选
模板继承机制
标准的调试系统
对于Jinja2的语法可重新配置,以适应不同的输出
注意:在使用Flask 0.10.1版本进行开发时,一定要安装Python3.3及以上版本,Flask 0.10.1不支持Python3.2及更旧的版本。
Ø Flask安装由于本书使用的是PyCharm,其中集成包含了Flask框架,因此Flask的安装与Django大同小异。
点击【Create New Project】用来创建新项目,如图所示。
点击左侧导航栏中的Flask,然后在右侧的Location中输入所建项目的地址及名称,在Interpreter中选择Python解释器,此处选择的是虚拟环境V_D2,最后点击Create即可建成项目flask1,如图所示。
创建完成如图所示。
Ø Flask实现第一行代码在创建好flask1项目后,接下来讲解如何使用Flask。众所周知,第一行代码是输出“Hello World!”,但是在Flask中有一个项目名称加上.py的文件,里面就包含输出“Hello World!”的代码,具体示例如下:
以上代码主要内容有:
导入Flask类。
创建Flask类的实例,第一个参数是应用模块或者包的名称。__name__为点一模块,若是有模块导入则不同。(即“__name__”的值为“__main__”或实际导入模块名称),Flask通过这个名称的不同来判断模板和所需文件的位置。
使用route()装饰器告知Flask能触发函数的URL,即绑定URL。
hello_world()的函数名在生成URL时被特定的函数采用,返回的内容显示在用户浏览器中。
用run()函数来运行应用。 其中if __name__ == '__main__'确保服务器只会在该脚本被Python解释器直接执行的时候才会运行,而不是作为模块导入的时候。
注意:403 Forbidden()会一直运行,因此不要在它之后写任何代码。
接下来运行上述示例,如图所示。
然后在浏览器中输入
http://127.0.0.1:5000/,结果如图所示。
至此,Flask的安装、概述和初步使用讲解完成,接下来的章节是对Flask使用及其他知识进行详细的讲解。
路由详解随着互联网的发展,现代Web应用的URL都十分的优雅,易于辨识记忆。若直接将某一部分的内容绑定为特定的URL,在访问网站时就会显示所需页面,而不是索引页,Flask的路由设置就能实现此功能。本节接下来讲解路由URL设置。
Ø 一般路由Flask中route()装饰器将定义的函数绑定到对应的URL上。一般路由的绑定如例所示。
在例中有两个函数分别是index()、hello()。对应的URL分别为
http://127.0.0.1:5000/、
http://127.0.0.1:5000/hello。
Ø 带参数的路由在上一小节中讲解了一般路由的配置以及绑定,接下来将讲解复杂的路由即带参数的路由配置。
1.在路径中添加变量参数在日常生活中URL不会是一成不变的,比如用户在登录某个网站时,会发现URL上会有一些变动,会出现一些变量的名称,而且这些变量的值会随着填入值的变化而变化,如例所示。
在使用route()函数进行绑定时可以通过<variable_name>的方式添加变量,如例中<username>,并应用在被映射的函数中。例运行结果如图所示。
2.指定变量的类型在声明变量时,若不想使用默认类型,可以指定变量的类型,如例所示。
例运行之后在浏览器中显示结果如图所示。
注意:
不指定变量类型则默认为path类型。
Flask中允许三种类型的变量映射,分别是int、float、path三种。
3.路径最后分隔符有无的区别在URL中都会出现“/”的分隔符,“/”在不同的位置所代表的内容是不相同的,如在开头则是一个绝对路径,在中间则是做隔离路径的层级,在末尾有两种情况,一种是有“/”,另一种是没有“/”,这两种情况还是存在较大的差别的,如例所示。
在浏览器中输入相关url即可查看路径最后分隔符有无的区别,如图所示。
在图中,有“/”作为结尾的路径在访问时不管最后加不加“/”都可以访问到相应的内容,但是没有“/”作为结尾的路径在访问时不加“/”可以正常访问相应的内容,而加了“/”则访问不到相应的内容,以上就是两者的区别。
Ø HTTP访问方式HTTP(超文本传输协议)有许多不同的访问URL的方法。在Flask中,路由默认只回应GET请求,但通过route()装饰器中methods参数可以改变这个行为,具体示例如下:
上述示例中,通过methods参数声明了两种访问方式:GET和POST,不管在客户端以何种方式请求 “/login”都会映射到login()函数,在函数中通过request.method属性来获取此次HTTP请求的方式。上述示例是将两种访问方式都映射到同一个函数中,当然为了灵活地运用URL与访问方法以及被映射函数的关系,Flask还可以通过把不同的访问方式赋予相同的URL,但映射不同的函数,具体示例如下:
上述示例通过访问方式的不同将“/login”这个URL映射到不同的函数中。
由于在HTTP中不同访问方式之间存在联系,因此在Flask中定义了两组隐式的规则。
当route装饰器中GET方式被指定,那么HEAD方式会自动加入该装饰器中
在Flask 0.6版本以后,当route装饰器中任何方式被指定,都会将OPTIONS方式加入该装饰器中。
在HTTP中有一些非常常见的访问方式,如表所示。
Ø 生成URL学习中可知Flask可以匹配URL,但有的时候,需要通过函数的名称来获得与其绑定的URL,即反向生成URL。在Flask中可以通过url_for()函数来实现这个功能,如例所示。
输出结果如图所示。
在程序中使用url_for()生成URL的原因有以下几点:
反向解析比硬编码的可读性以及可维护性都更好,当需修改路由函数中的URL地址时,不需要去更改和调用url_for处的代码。
URL构建生成时会自动将特殊字符和Unicode数据转义,省去很多麻烦。
Jinja2模板Ø 初识Jinja2若大家在此之前有接触过其它的基于文本的模板语言,比如Smarty或者本书第6章所讲解的Django,那么 Jinja2 会让大家有眼前一亮的感觉。接下来先用一个简点的实例来了解Jinja2模板引擎,如例所示。
首先在项目中的templates文件夹下创建两个模板文件,分别为index.html、user.html,在两个文件中分别编写以下内容。
index.html:user.html:然后再修改flask1.py中的内容,代码如下。
flask1.py:在例中,Flask在程序项目下的templates子文件夹中寻找模板,然后通过Flask 提供的render_template()函数把Jinja2模板引擎集成到程序中,(render_template()函数的第一个参数是模板的文件名,其他的参数都是键值对,表示模板中变量对应的真实值)最终将模板内容渲染出来。渲染显示结果如图所示。
Ø Jinja2基础语法从第一小节的内容中可以发现使用Jinja2开发网站事半功倍,因为它将分离的模板和渲染两部分内容进行结合,最终达成所需效果。接下来开始讲解Jinja2的一些基础语法知识。
Jinja2模板主要由普通内容、变量、表达式、标签和注释五部分内容组成,其中五部分内容的具体含义如下所示:
普通内容:无特殊意义的内容,模板渲染时不进行解释。
变量:在模板渲染时会被传入的真实值替换。
表达式:对变量进行算术或逻辑操作。
标签:用于在模板渲染时进行逻辑控制。
注释:模板渲染时删除的内容(即不显示的内容)。
下面通过一个示例来对Jinja2的基础语法进行讲解,具体示例如下:
上述示例是一个模板示例,其中大多数的HTML标签(如<head>、<body>、<li>等)都是普通内容,模板渲染的时候不进行解释,还有一些用特殊格式定义的内容,如下所述:
{{…}}:装载变量或者是表达式,模板渲染的时候,会将同名参数的真实值与这个变量替换。如本例中的item(item.href、item.caption)、a_variable、user.name、user['name']等等。
{%...%}:装载控制语句。本例中声明了一个根据navigation变量元素进行迭代的循环体,使用for语句进行控制。
{#...#}:装载注释内容。本例中注释内容为“a comment”,这一部分的内容不会出现在渲染结果中,在渲染过程中会将此处内容删除。
调用该模板与例大同小异,使用render_template()函数进行传值渲染,具体示例如下:
模板渲染之后的HTML如下:
Ø 控制结构展示控制结构中的for循环,除此之外,控制结构还包括很多其他结构。本节内容主要是对Jinja2模板中的控制结构进行讲解。
1.选择(判断)选择控制结构与Python中类似,没有多大差别,此处不再赘述,在下一个内容循环结构的案例中加以应用。
2.循环循环在上一小节中已经有所了解,接下来讲解循环当中需要注意的一些知识点。模板中循环与Python中不同,不能使用break或continue来进行控制循环,但可以通过一些特殊的变量来控制循环。
具体如表所示。
具体示例如下:
将内容修改为上述示例,其中使用了loop.first这个特殊变量使得循环不显示第一个值。上述示例使用了{%if%}和{%endif%}来对循环的结果进行判断选择,也就是上一部分知识点的内容。
渲染之后的HTML如下所示:
从渲染后的HTML中可以看到,navigation中的第一条数据并没有渲染出来,即<li><a href="杭州千锋互联科技有限公司">1000phone</a></li>这一条内容,因此在模板中可以通过这些特殊变量来控制循环。
3.测试在Jinja2模板引擎的术语中,测试(Test)是根据变量或表达式的值生成布尔结果的一种函数工具,使用时需要在变量或表达式后加“is”和测试名称,具体示例如下:
在实际编程开发过程中会遇到许多需要测试的变量以及表达式,而且这些测试在循环和判断控制语句中起关键性作用,因此大家需要熟练掌握一些常用的测试函数表。
4.宏Jinja2模板还支持宏(macro),宏其实类似于Python中的函数,宏的使用具体示例如下:
宏的定义:
宏的使用:
为了方便宏的重复使用,可以将宏定义在一个点独的文件中,使用时直接在代码中引用,具体示例如下:
Ø过滤器在Django的学习中讲解了过滤器的相关知识,在Jinja2模板中也有过滤器,主要作用与Django中大同小异,而且Jinja2不仅有内置的过滤器,还可以自定义过滤器,接下来讲解Jinja2中的内置过滤器。
Ø 模板继承对于一个网站来说,会有不同的显示页面,但是这些页面中存在许多相同内容,比如页头、导航栏、页尾等等。这些相同的部分都可以使用Jinja2中的模板继承来完成,即将这些相同部分内容集中编写到一个“基模板”中,然后在不同的页面中继承“基模板”,从而导入其内容,最终达到公共内容集中而且易于修改的目的。
SQLAlchemySQLAlchemy是Python编程语言下的一款开源软件,提供了SQL工具包及对象关系映射(ORM)工具,而且是Python中最有名ORM框架。它主要是为高效和高性能的数据库访问设计,实现了完整的企业级持久模型。其理念是SQL数据库的量级和性能重要于对象集合,而对象集合的抽象又重要于表和行。
Ø
SQLAlchemy安装首先需要安装SQLAlchemy库,因此接下来先学习如何在PyCharm中安装SQLAlchemy库。
在PyCharm中点击File,然后再点击settings,如图所示。
点击Project:flask1(此处flask1是项目名称),再点击Project Interpreter,如图所示。
在图中,点击右侧绿色的【+】,然后在搜索框中输入SQLAlchemy,找到SQLAlchemy并选中,之后直接点击Install Package即可安装,如图所示。
SQLAlchemy安装成功,如图所示。
安装SQLAlchemy成功之后,就可以在项目中导入并使用这个库了。
使用SQLAlchemy有四种方法,分别是Flask-SQLAlchemy扩展、显示调用、手动实现ORM、SQL抽象层。由于本章主要是使用Flask框架,因此建议使用第一种方法。
Flask-SQLAlchemy扩展包中包含了SQLAlchemy,因此安装Flask-SQLAlchemy扩展(安装方式如SQLAlchemy安装)就可以使用SQLAlchemy库了。使用时直接导入即可,具体示例如下:
Ø
SQLAlchemy的初使用安装了扩展包之后接下来讲解如何使用SQLAlchemy,本节以一个案例来讲解SQLAlchemy的使用,如例所示。
SQLAlchemy的使用
1.创建SQLAlchemy配置文件配置文件名为database.py,配置文件代码如下。
配置文件中前3行都是导入内容,第1行是导入flask的核心类Flask,第2行是从flask_sqlalchemy扩展包中导入SQLAlchemy,第3行导入os库为了方便定位。从第4到第8行是配置信息,第4行是将当前文件传入dirname()函数中,获取当前文件所在路径,abspath()函数获取该文件所在的绝对路径,以便在配置数据库的路径时使用;第6、7、8行中SQLALCHEMY_DATABASE_URI:用于连接数据库,更多主流数据库的连接方式如表所示。SQLALCHEMY_TRACK_MODIFICATIONS:若设置成True(默认情况),Flask-SQLAlchemy将会追踪对象的修改并且发送信号,这需要额外的内存,如果非必要时可以禁用它;若不显式的调用它,在最新版的运行环境下,会显示警告。第9行是SQLAlchemy()函数,将刚刚创建的Flask框架与工程所需要使用的数据库绑定到一起,以便实现工程与数据库连接,实现数据操作。最后两行就是手动创建函数,以便初始化数据库,以上是整个配置文件内容。
2.创建映射表对于一个数据库,其中最主要的就是数据,而数据都放在数据表中,在工程中需要创建映射表,以便将表映射到数据库中,达到创建表的作用。
接下来在database.py中创建一个简点的User数据表,具体示例如下:
第2行到最后是创建User类。User继承了db.model类,将当前创建的映射表和数据库db绑定在一起,若此时工程文件调用create_all()函数,那么会自动将绑定后的映射表文件创建在数据库文件中。db.Column用来创建映射表字段,常用类型如表所示。
primary_key=True设置当前字段为主键,unique=True设置当前字段不可重复。最后的__repr__()函数是为以后调试输出提供接口。
3.创建数据库直接调用db.create_all()函数就可以创建数据库了,如图所示。
创建之后在项目的根目录下就会出现test.db的数据库文件,如图所示。
创建完之后可以通过以下方式进行验证。在项目编写环境的右侧点击Database,之后点击绿色的【+】,找到Data Source,然后找到Sqlite (Xerial)并点击,如图所示。
然后在File中选中生成的test.db文件,其他内容都会自动生成,然后在点击【OK】之前要确保安装了缺失插件,如图所示。
若缺少插件,会在no object下方出现Download字样,插件一定要安装,否则会出错,直接点击Download即可安装,如图所示。
确认安装好插件之后点击OK,显示界面如图所示,说明数据库以及数据表创建成功。
Ø 使用SQLAlchemy进行数据库操作已经讲解了如何使用SQLAlchemy创建数据库以及映射表,创建好之后接下来讲解使用SQLAlchemy进行数据操作,如数据的增删改查。
1.insert.py第3~6行相当于将SQL语句赋值给对象。第7~10行将对应数据库的操作保存在缓存中,既然是保存到缓存中,那么该数据库语句还没有提交到数据库中。第11行commit()和数据库中的commit指令一样,将数据库操作提交到数据库中。运行之后数据库中结果如图所示。
2.delete.py调用delete()函数,将数据传入db对象,并提交到数据库中。
3.update.py首先将对象查询出来,然后将修改的字段赋值,并将查询出的对象提交到数据库。
4.select1.py1)一般查询
此处的查询是将所有用户的信息按照id、user_name、email的形式输出内容,只是一个简点的查询输出操作。运行结果如图所示。
2)精确查询
现实生活中会遇到一些需要精确查询的情况,如买火车票、飞机票时需要查询的是目的地的准确余票,而在实际开发工作中,同样会需要使用到精确查询,具体示例如下:
运行结果如图所示。
3)模糊查询
在生活中,学生在图书馆查找关于Python的书籍,只需输入Python字样,所有含有Python字样的书籍都会显示出来,此时便使用了模糊查询。在实际开发中,某些项目也会需要提供模糊查找的功能,具体示例如下:
运行结果如图所示。
4)其他查询条件
其他查询条件如表所示。
在query对象上调用的常见过滤器如表所示。
在查询上应用指定过滤器后,通过调用执行函数来执行查询,最后返回结果。常用的查询执行函数如表所示。
WTForm表点在Web开发中,表点是整个互动式网站进行客户端和服务器端交互的核心。在实际开发中,由于现在网页内容越来越丰富,若开发者直接请求上下文获取客户端数据并解析,会出现逻辑混乱的局面。在Flask框架中有一个WTForm表点库,可以大大简化表点的处理,可读性也非常高,因此可以很好地解决上述问题。接下来讲解使用WTForm进行表点处理。
Ø 表单定义在定义表点之前先要安装WTForm表点插件flask-wtf,安装方式与安装SQL-Alchemy一样,安装成功后就可以对表点进行定义了。接下来以用户登录表点为例进行讲解,如例所示。
先导入以上包,其中“from flask_wtf import FlaskForm”是导入Form表点,“from wtforms import StringField,PasswordField”是导入HTML标准字段,此处的StringField是文本字段,PasswordField是密码文本字段,常用的HTML字段类型如表所示。
接下来定义表点类MyForm,继承自FlaskForm,主要包含两部分内容user(用户名)和pwd(密码)。
其中“from wtforms.validators import DataRequired”是导入验证函数,DataRequired代表数据必填项,具体在表点验证中讲解。
接下来定义表点类MyForm,继承自FlaskForm,主要包含两部分内容user(用户名)和pwd(密码)。
Flask为了防范跨站请求伪造技术(cross-site request forgery,CSRF )攻击,默认在使用flask-wtf之前要求app一定要设置secret_key,即上述代码中的app.secret_key。
将表点定义好后开始编写前端HTML模板,以下是login.html模板文件代码。
Ø 模板编写在login.html中使用{{ url_for('login') }}将数据提交到/login这个路由下。表点中,“form.hidden_tag()”会生成一个隐藏的“<div>”标签,其中会渲染任何隐藏的字段,最主要的是CSRF字段。WTForms默认开启CSRF保护,若要关闭它(不建议这样做),可以在实例化表点时传入参数,如“form = MyForm(csrf_enabled=False)”。
Ø 接收表单数据login.html模板文件将用户在浏览器端输入的数据信息传送过来之后,需要进行接收并判断是否符合要求。以下示例是接收数据的代码:
先声明MyForm实例对象form,使用if语句判断submit是否点击提交,然后再对‘user’、‘pwd’进行简点的判断,若均符合,则将返回的信息重新渲染到login.html文件中。
具体结果如图所示。
若用户名和密码输入错误,运行结果如图所示。
Ø 表单验证在WTForm表点中有很多验证函数,常用的验证函数如表所示,用于各种表点数据的验证,例中的DataRequired就是其中之一。
小结:
主要讲解了Flask框架的基础以及使用,尤其是对其中的路由设置、Jinja2模板、SQLAlchemy数据库插件、WTForm表点插件等知识进行着重讲解,这几个部分的内容属于Flask框架的重点。
第三课时