用Python进行Web开发——Flask框架入门学习

若你对Web开发不够了解,可以先看一下:用Python进行Web开发——基础介绍

1 Flask 概述

Web Framework:Web Application Framework(Web应用程序框架)或简单的Web Framework(Web框架)表示一个库和模块的集合,使Web应用程序开发人员能够编写应用程序,而不必担心协议,线程管理等低级细节。

Flask:一个用Python编写的Web应用程序框架。 它由 Armin Ronacher 开发,他领导一个名为Pocco的国际Python爱好者团队。 Flask基于Werkzeug WSGI工具包和Jinja2模板引擎。两者都是Pocco项目。

WSGI:Web Server Gateway Interface(Web服务器网关接口,WSGI)已被用作Python Web应用程序开发的标准。 WSGI是Web服务器和Web应用程序之间通用接口的规范。

Werkzeug:它是一个WSGI工具包,它实现了请求,响应对象和实用函数。 这使得能够在其上构建web框架。 Flask框架使用Werkzeug作为其基础之一。

jinja2:Python的一个流行的模板引擎。Web模板系统将模板与特定数据源组合以呈现动态网页。

Flask通常被称为微框架。 它旨在保持应用程序的核心简单且可扩展。Flask没有用于数据库处理的内置抽象层,也没有形成验证支持。相反,Flask支持扩展以向应用程序添加此类功能。

2 Flask 应用

Hello.py:

from flask import Flask   # 必须在项目中导入Flask模块。 Flask类的一个对象是我们的WSGI应用程序。
app = Flask(__name__) # Flask构造函数使用当前模块(__name __)的名称作为参数。

@app.route('/')
def hello_world():
   return 'Hello World'

if __name__ == '__main__':
   app.run()

Flask类的 route() 函数是一个装饰器,它告诉应用程序哪个URL应该调用相关的函数。

app.route(rule, options)
  • rule 参数表示与该函数的URL绑定。
  • options 是要转发给基础Rule对象的参数列表。

在上面的示例中,'/ ' URLhello_world()函数绑定。因此,当在浏览器中打开web服务器的主页时,将呈现该函数的输出。

最后,Flask类的run()方法在本地开发服务器上运行应用程序。

app.run(host, port, debug, options)
  • host:要监听的主机名。 默认为127.0.0.1(localhost)。设置为“0.0.0.0”以使服务器在外部可用
  • port:默认值为5000
  • debug:默认为false。 如果设置为true,则提供调试信息
  • options:要转发到底层的Werkzeug服务器。

调试模式
通过调用run()方法启动Flask应用程序。但是,当应用程序正在开发中时,应该为代码中的每个更改手动重新启动它。为避免这种不便,应启用调试支持。如果代码更改,服务器将自行重新加载。它还将提供一个有用的调试器来跟踪应用程序中的错误(如果有的话)。

在运行或将调试参数传递给run()方法之前,通过将application对象的debug属性设置为True来启用Debug模式

app.debug = True
app.run()
app.run(debug = True)

3 Flask 路由

现代Web框架使用路由技术来帮助用户记住应用程序URL。可以直接访问所需的页面,而无需从主页导航。

Flask中的route()装饰器用于将URL绑定到函数。例如:

@app.route(/hello’)
def hello_world():
   return ‘hello world’

在这里,URL '/ hello'规则绑定到hello_world()函数。 因此,如果用户访问http:// localhost:5000 / hello URLhello_world()函数的输出将在浏览器中呈现。

application对象的add_url_rule()函数也可用于将URL与函数绑定,如上例所示,使用route()

装饰器的目的也由以下表示:

def hello_world():
   return ‘hello world’
app.add_url_rule(/, ‘hello’, hello_world)

4 Flask 变量规则

通过向规则参数添加变量部分,可以动态构建URL。此变量部分标记为<variable-name>。它作为关键字参数传递给与规则相关联的函数。

在以下示例中,route()装饰器的规则参数包含附加到URL '/hello'<name>。在浏览器中输入http://localhost:5000/hello/w3cschool作为URL,则’w3cschool’将作为参数提供给hello()函数。

from flask import Flask
app = Flask(__name__)

@app.route('/hello/<name>')
def hello_name(name):
   return 'Hello %s!' % name

if __name__ == '__main__':
   app.run(debug = True)

除了默认字符串变量部分之外,还可以使用以下转换器构建规则:

  • int:接受整数
  • float:对于浮点值
  • path:接受用作目录分隔符的斜杠

在下面的代码中,使用了所有这些构造函数:

from flask import Flask
app = Flask(__name__)

@app.route('/blog/<int:postID>')
def show_blog(postID):
   return 'Blog Number %d' % postID

@app.route('/rev/<float:revNo>')
def revision(revNo):
   return 'Revision Number %f' % revNo

if __name__ == '__main__':
   app.run()

Flask的URL规则基于Werkzeug的路由模块。这确保形成的URL是唯一的,并且基于Apache规定的先例。

考虑以下脚本中定义的规则:

from flask import Flask
app = Flask(__name__)

@app.route('/flask')
def hello_flask():
   return 'Hello Flask'

@app.route('/python/')
def hello_python():
   return 'Hello Python'

if __name__ == '__main__':
   app.run()

这两个规则看起来类似,但在第二个规则中,使用斜杠(/)。因此,它成为一个规范的URL,使用 /python/python/返回相同的输出。但是,如果是第一个规则,/flask/ URL会产生“404 Not Found”页面。

5 Flask URL构建

url_for()函数对于动态构建特定函数的URL非常有用。该函数接受函数的名称作为第一个参数,以及一个或多个关键字参数,每个参数对应于URL的变量部分。

以下脚本演示了如何使用url_for()函数:

from flask import Flask, redirect, url_for
app = Flask(__name__)
@app.route('/admin')
def hello_admin():
   return 'Hello Admin'


@app.route('/guest/<guest>')

def hello_guest(guest):
   return 'Hello %s as Guest' % guest


@app.route('/user/<name>')
def hello_user(name):  # 接受来自URL的参数的值
   if name =='admin':  # 检查接收的参数是否与'admin'匹配
      return redirect(url_for('hello_admin'))  # 匹配,则使用url_for()将应用程序重定向到hello_admin()函数
   else:
      return redirect(url_for('hello_guest',guest = name))  # 否则重定向到将接收的参数作为guest参数传递给它的hello_guest()函数


if __name__ == '__main__':
   app.run(debug = True)

6 Flask HTTP方法

Http协议是万维网中数据通信的基础。在该协议中定义了从指定URL检索数据的不同方法。

以下是不同的http方法:

  1. GET:以未加密的形式将数据发送到服务器。最常见的方法。
  2. HEAD:和GET方法相同,但没有响应体。
  3. POST:用于将HTML表单数据发送到服务器。POST方法接收的数据不由服务器缓存。
  4. PUT:用上传的内容替换目标资源的所有当前表示。
  5. DELETE:删除由URL给出的目标资源的所有当前表示。

默认情况下,Flask路由响应GET请求。但是,可以通过为route()装饰器提供方法参数来更改此首选项。

为了演示在URL路由中使用POST方法,首先创建一个HTML表单,并使用POST方法将表单数据发送到URL。

将以下脚本另存为login.html:

<html>
   <body>
      
      <form action = "http://localhost:5000/login" method = "post">
         <p>Enter Name:</p>
         <p><input type = "text" name = "nm" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>
      
   </body>
</html>

现在在Python shell中输入以下脚本:

from flask import Flask, redirect, url_for, request
app = Flask(__name__)

@app.route('/success/<name>')
def success(name):
   return 'welcome %s' % name

@app.route('/login',methods = ['POST', 'GET'])
def login():
   if request.method == 'POST':
      user = request.form['nm']
      return redirect(url_for('success',name = user))
   else:
      user = request.args.get('nm')
      return redirect(url_for('success',name = user))

if __name__ == '__main__':
   app.run(debug = True)

开发服务器开始运行后,在浏览器中打开login.html,在文本字段中输入name,然后单击提交
在这里插入图片描述
表单数据将POST到表单标签的action子句中的URL。

http://localhost/login映射到login()函数。由于服务器通过POST方法接收数据,因此通过以下步骤获得从表单数据获得的“nm”参数的值:

user = request.form['nm']

它作为变量部分传递给'/ success'URL。浏览器在窗口中显示welcome消息。
在这里插入图片描述
在login.html中将方法参数更改为**‘GET’,然后在浏览器中再次打开它。服务器上接收的数据是通过GET**方法获得的。通过以下的步骤获得’nm’参数的值:

User = request.args.get(‘nm’)

这里,args是包含表单参数对及其对应值对的列表的字典对象。与’nm’参数对应的值将像之前一样传递到'/ success'URL。

7 Flask 模板

在前面的实例中,视图函数的主要作用是生成请求的响应,这是最简单请求.实际上,视图函数有两个作用:

  • 处理业务逻辑
  • 返回响应内容

在大型应用中,把业务逻辑和表现内容放在一起,会增加代码的复杂度和维护成本.

模板其实是一个包含响应文本的文件,其中用占位符(变量)表示动态部分,告诉模板引擎其具体的值需要从使用的数据中获取。

使用真实值替换变量,再返回最终得到的字符串,这个过程称为**‘渲染’**
Flask 是使用 Jinja2 这个模板引擎来渲染模板

使用模板的好处:

  • 视图函数只负责业务逻辑和数据处理(业务逻辑方面)
  • 而模板则取到视图函数的数据结果进行展示(视图展示方面)
  • 代码结构清晰,耦合度低

7.1 模板基本使用

在项目下创建 templates 文件夹,用于存放所有模板文件,并在目录下创建一个模板文件 html 文件 hello.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
我的模板html内容
</body>
</html>

创建视图函数,将该模板内容进行渲染返回:

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('hello.html')

7.2 模板变量

代码中传入字符串,列表,字典到模板中:

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    # 往模板中传入的数据
    my_str = 'Hello Word'
    my_int = 10
    my_array = [3, 4, 2, 1, 7, 9]
    my_dict = {
        'name': 'xiaoming',
        'age': 18
    }
    return render_template('hello.html',
                           my_str=my_str,
                           my_int=my_int,
                           my_array=my_array,
                           my_dict=my_dict
                           )

模板中代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  我的模板html内容
  <br />{{ my_str }}
  <br />{{ my_int }}
  <br />{{ my_array }}
  <br />{{ my_dict }}
</body>
</html>

运行效果:

我的模板html内容
Hello Word
10
[3, 4, 2, 1, 7, 9]
{'name': 'xiaoming', 'age': 18}

7.3 示例代码

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    my_int = 18
    my_str = 'curry'
    my_list = [1, 5, 4, 3, 2]
    my_dict = {
        'name': 'durant',
        'age': 28
    }

    # render_template方法:渲染模板
    # 参数1: 模板名称  参数n: 传到模板里的数据
    return render_template('hello.html',
                           my_int=my_int,
                           my_str=my_str,
                           my_list=my_list,
                           my_dict=my_dict)


if __name__ == '__main__':
    app.run(debug=True)
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>

<body>
  <h2>我是模板</h2>
  {{ my_int }}
  <br>
  {{ my_str }}
  <br>
  {{ my_list }}
  <br>
  {{ my_dict }}
  <hr>
  <h2>模板的list数据获取</h2>
  <hr>
  {{ my_list[0] }}
  <br>
  {{ my_list.1 }}
  <hr>
  <h2>字典数据获取</h2>
  <hr>
  {{ my_dict['name'] }}
  <br>
  {{ my_dict.age }}
  <hr>
  <h2>算术运算</h2>
  <br>
  {{ my_list.0 + 10 }}
  <br>
  {{ my_list[0] + my_list.1 }}
</body>

</html>

8 Flask 静态文件

Web应用程序通常需要静态文件,例如 javascript 文件或支持网页显示的 CSS 文件。通常,配置Web服务器并为您提供这些服务,但在开发过程中,这些文件是从您的包或模块旁边的static文件夹中提供,它将在应用程序的/static中提供。特殊端点static用于生成静态文件的URL。

在下面的示例中,在 index.html 中的HTML按钮的OnClick事件上调用 hello.js 中定义的 javascript 函数,该函数在Flask应用程序的“/”URL上呈现。

from flask import Flask, render_template
app = Flask(__name__)

@app.route("/")
def index():
   return render_template("index.html")

if __name__ == '__main__':
   app.run(debug = True)

index.html 的HTML脚本如下所示:

<html>

   <head>
      <script type = "text/javascript" 
         src = "{{ url_for('static', filename = 'hello.js') }}" ></script>
   </head>
   
   <body>
      <input type = "button" onclick = "sayHello()" value = "Say Hello" />
   </body>
   
</html>

Hello.js包含sayHello()函数:

function sayHello() {
   alert("Hello World")
}

9 Flask Request对象

来自客户端网页的数据作为全局请求对象发送到服务器。为了处理请求数据,应该从Flask模块导入。

Request对象的重要属性如下所列:

  • Form - 它是一个字典对象,包含表单参数及其值的键和值对。
  • args - 解析查询字符串的内容,它是问号(?)之后的URL的一部分。
  • Cookies - 保存Cookie名称和值的字典对象。
  • files - 与上传文件有关的数据。
  • method - 当前请求方法。

10 Flask 将表单数据发送到模板

我们可以在 URL 规则中指定 http 方法。触发函数接收的 Form 数据可以以字典对象的形式收集它,并将其转发到模板,以在相应的网页上呈现它。

在以下示例中,'/' URL 会呈现具有表单的网页(student.html)。填入的数据会发布到触发 result() 函数的 '/result' URL。

result() 函数收集字典对象中的 request.form 中存在的表单数据,并将其发送给 result.html。

该模板动态呈现表单数据的 HTML 表格。
下面给出的是应用程序的 Python 代码:

from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def student():
   return render_template('student.html')


@app.route('/result',methods = ['POST', 'GET'])
def result():
   if request.method == 'POST':
      result = request.form
      return render_template("result.html",result = result)


if __name__ == '__main__':
   app.run(debug = True)

下面给出的是 student.html 的 HTML 脚本:

<form action="http://localhost:5000/result" method="POST">
     <p>Name <input type = "text" name = "Name" /></p>
     <p>Physics <input type = "text" name = "Physics" /></p>
     <p>Chemistry <input type = "text" name = "chemistry" /></p>
     <p>Maths <input type ="text" name = "Mathematics" /></p>
     <p><input type = "submit" value = "submit" /></p>
  </form>

下面给出了模板( result.html )的代码:

<!doctype html>
  <table border = 1>
     {% for key, value in result.items() %}
    <tr>
       <th> {{ key }} </th>
       <td> {{ value }}</td>
    </tr>
 {% endfor %}
</table>

运行 Python 脚本,并在浏览器中输入 URL http://localhost:5000/
在这里插入图片描述
当点击提交按钮时,表单数据以 HTML 表格的形式呈现在 result.html 上。
在这里插入图片描述

11 Flask Cookies

Cookie 以文本文件的形式存储在客户端的计算机上。其目的是记住和跟踪与客户使用相关的数据,以获得更好的访问者体验和网站统计信息。

Request对象包含 Cookie 的属性。它是所有cookie变量及其对应值的字典对象,客户端已传输。除此之外,cookie还存储其网站的到期时间,路径和域名。

在Flask中,对cookie的处理步骤为:

  1. 设置cookie:
    设置cookie,默认有效期是临时cookie,浏览器关闭就失效。可以通过 max_age 设置有效期, 单位是秒。
resp = make_response("success")   # 设置响应体
 resp.set_cookie("w3cshool", "w3cshool", max_age=3600)

2.获取cookie
获取cookie,通过 request.cookies 的方式, 返回的是一个字典,可以获取字典里的相应的值。

cookie_1 = request.cookies.get("w3cshool")

3.删除cookie
这里的删除只是让cookie 过期,并不是直接删除cookie。删除cookie,通过delete_cookie()的方式, 里面是cookie的名字。

resp = make_response("del success")  # 设置响应体
resp.delete_cookie("w3cshool")

以下为Flask Cookies的简单示例:

from flask import Flask, make_response, request

app = Flask(__name__)

@app.route("/set_cookies")
def set_cookie():
    resp = make_response("success")
    resp.set_cookie("w3cshool", "w3cshool",max_age=3600)
    return resp

@app.route("/get_cookies")
def get_cookie():
    cookie_1 = request.cookies.get("w3cshool")  # 获取名字为Itcast_1对应cookie的值
    return cookie_1

@app.route("/delete_cookies")
def delete_cookie():
    resp = make_response("del success")
    resp.delete_cookie("w3cshool")

    return resp

if __name__ == '__main__':
    app.run(debug=True)

设置cookies
运行应用程序,在浏览器中输入 127.0.0.1:5000/set_cookies 来设置cookies,设置 cookies 的输出如下所示:
在这里插入图片描述
获取cookie
根据视图函数中相对应的路径,输入 http://127.0.0.1:5000/get_cookies ,读回 cookies 的输出如下所示:
在这里插入图片描述
删除cookie
根据视图函数中相对应的路径,输入 http://127.0.0.1:5000/delete_cookies ,删除 cookies (只是让 cookie 过期) 的输出如下所示:
在这里插入图片描述

12 Flask Sessions 会话

与Cookie不同,Session(会话)数据存储在服务器上。会话是客户端登录到服务器并注销服务器的时间间隔。需要在该会话中保存的数据会存储在服务器上的临时目录中。

为每个客户端的会话分配会话ID。会话数据存储在cookie的顶部,服务器以加密方式对其进行签名。对于此加密,Flask应用程序需要一个定义的SECRET_KEY

Session对象也是一个字典对象,包含会话变量和关联值的键值对。例如,要设置一个’username’会话变量:Session[‘username’] = ’admin’
要释放会话变量,使用pop()方法:session.pop('username', None)

以下代码是Flask中的会话工作的简单演示。URL'/'只是提示用户登录,因为未设置会话变量'username'

@app.route('/')
def index():
   if 'username' in session:
      username = session['username']
         return 'Logged in as ' &plus; username &plus; '<br>' &plus; \
         "<b><a href = '/logout'>click here to log out</a></b>"
   return "You are not logged in <br><a href = '/login'></b>" &plus; \
      "click here to log in</b></a>"

当用户浏览到“/login”login()视图函数时,因为它是通过GET方法调用的,所以将打开一个登录表单。

表单发送回'/login',现在会话变量已设置。应用程序重定向到'/'。此时会话变量'username'被找到。

@app.route('/login', methods = ['GET', 'POST'])
def login():
   if request.method == 'POST':
      session['username'] = request.form['username']
      return redirect(url_for('index'))
   return '''
	
   <form action = "" method = "post">
      <p><input type = text name = username/></p>
      <p<<input type = submit value = Login/></p>
   </form>
	
   '''

应用程序还包含一个logout()视图函数,它会弹出’username'会话变量。因此,'/'URL再次显示开始页面。

@app.route('/logout')
def logout():
   # remove the username from the session if it is there
   session.pop('username', None)
   return redirect(url_for('index'))

运行应用程序并访问主页。(确保设置应用程序的secret_key

from flask import Flask, session, redirect, url_for, escape, request
app = Flask(__name__)
app.secret_key = 'any random string’

13 Flask 重定向和错误

Flask类有一个redirect()函数。调用时,它返回一个响应对象,并将用户重定向到具有指定状态代码的另一个目标位置。

redirect()函数的原型如下:Flask.redirect(location, statuscode, response)

  • location:应该重定向响应的URL。
  • statuscode:发送到浏览器标头,默认为302。
  • response:用于实例化响应。

以下状态代码已标准化:

  • HTTP_300_MULTIPLE_CHOICES
  • HTTP_301_MOVED_PERMANENTLY
  • HTTP_302_FOUND
  • HTTP_303_SEE_OTHER
  • HTTP_304_NOT_MODIFIED
  • HTTP_305_USE_PROXY
  • HTTP_306_RESERVED
  • HTTP_307_TEMPORARY_REDIRECT

默认状态代码为302,表示’found’。

Flask类具有带有错误代码abort()函数:Flask.abort(code)
Code参数采用以下值之一:

  • 400 - 用于错误请求
  • 401 - 用于未身份验证的
  • 403 - Forbidden
  • 404 - 未找到
  • 406 - 表示不接受
  • 415 - 用于不支持的媒体类型
  • 429 - 请求过多

参考资料
https://www.w3cschool.cn/flask/flask_overview.html

  • 3
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值