Flask web开发基础

1,145 阅读6分钟

Flask是一个免费的web框架,也是一个年轻、充满活力的小型框架,开发文档齐全,社区活跃度高,有着众多支持者。Flask的设计目标是实现一个WSGI的微框架,其核心代码十分简单。

Flask框架介绍

Flask框架在中小型企业中的占有率比较高web框架,一般是用于开发轻量级web应用程序,Flask框架在市场占用率来说排名也是比较靠前的。本文主要介绍的内容是Flask框架的基本知识,包括它的基本结构以及它与Django框架的对比。

Flask框架的基本结构

Flask框架主要依赖两个库:werkzeug和jinja2。

werkzeug:是一个WSGI工具集,是web应用程序和多种服务器之间的标准python接口。

jinja2:负责渲染模板,将HTML、CSS和JavaScript组成的模板文件显示出来。

Flask框架的基本结构图,如下所示:

为了提高开发效率,减少冗余的代码,Flask框架会抽闲处web开发中的共同部分,以便在不同的页面中多次使用该部分。当客户端想要从web服务器中获取某些信息数据时,便会发起一个HTTP请求(例如,我们平时在浏览器中输入一个URL),Web应用会在后台,进行相应的业务处理(例如,读取数据库或者进行一些计算),然后读取用户需要的数据,生成相应的HTTP响应。如果访问的是静态资源,那么直接返回资源即可,不需要进行业务操作。

安装Flask

在这里我是建议各位读者安装anaconda,用于创建虚拟环境以及安装第三方库。

在Windows系统上安装flask

pip install flask

初识Flask web程序

下面用一段程序来演示Flask框架开发web程序的过程

from json.tool import main
import flask    # 导入falsk模块
app = flask.Flask(__name__)  #实例化flask
@app.route('/') # 装饰器操作,实现URL地址
def hello():    # 定义业务处理函数hello()
    return "这个是我们的第一个flask程序"

if __name__ == '__main__':
    app.run()   # 运行程序

分析web程序的基本结构

app.run()

上述代码的功能是调用flask类方法中的run()在本地服务器上运行当前flask web程序,当前flask web程序的名字是app,run方法的原型如下:

(method) run: (host: str | None = None, port: int | None = None, debug: bool | None = None, load_dotenv: bool = True, **options: Any) -> None

其中的三个参数是比较常用,但都是可选参数。

  • host:运行当前flask程序的主机名,默认值是127.0.0.1或者是localhost
  • port:运行当前flask程序的主机对应的端口号,默认值是5000
  • debug:设置是否显示调试信息,默认值是False,如果设置为True,则显示调试信息,建议读者在开发程序的过程中可以将调试信息打开。

调试的目的是在调试代码的过程中,如果代码发生改变,那么服务器会自动重启并运行Flask web程序,在此提高程序运行的效果。如果没有设置为调试模式,那每一次都需要手动重启程序,相当的麻烦。

路由处理

目前在web开发领域中,主流的第三方框架主要还是使用URL路由技术,访问某个特定的页面。在Flask web程序中,客户端(浏览器)把请问访问发送给web服务器,web服务器再将请求发送给flask web程序。flask框架将路由与python函数是一个映射关系。

flask框架支持三种路由技术

(1)使用路由方法route()

在Flask框架中,通过使用路由函数route(),将一个普通的哈数与特定的URL关联起来。当Web服务器收到URL请求时,会调用route()关联的函数并返回函数响应内容。

@app.route('/hello')
def hello():
    return "你好,我是python"

在浏览器中输入http://127.0.0.1:5000/hello,即会出现响应内容。

(2)路由方法add_url_rule()

def hello():
    return "你好,我是python"
app.add_url_rule('/hello', 'hello', hello)

(3)将不同的URL映射到同一个函数

在Flask Web中,可以使用多个不同的URL来同时映射到多个函数中。只需要设置两个装饰器即可。

@app.route('/')
@app.route('/hello')
def hello():    # 定义业务处理函数hello()
    return "这个是我们的第一个flask程序"

处理URL参数

在web程序中,URL并不一定是静止不变的,可能会存在动态的情况,需要在对应处理函数中的列表参数声明变量名。

from unicodedata import name
from flask import Flask
app = Flask(__name__)


@app.route('/hello/<name>')
def hello(name):
    return '你好 %s' % name

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

其中URL中的参数name是一个变量,如果在浏览器中输入

http://127.0.0.1:5000/hello/jack

那么“jack”将会作为参数参数,传递给hello()函数,因此,运行结果如下所示:

在Flask框架的URL中,除了可以使用字符串类型参数之外,还可以使用以下参数:

  • int:表示整型参数,例如"/hello/1"
  • float:表示浮点型参数,例如"hello/1.1"
from tkinter import N
from flask import Flask
app = Flask(__name__)


@app.route('/blog/<int:ID>')
def show_age(ID):
    return '我的年龄是:%d' % ID + '岁'

@app.route('/rev/<float:No>')
def show_money(No):
    return '我的身高是%f' % No + 'cm'


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

运行上述代码之后,在浏览器中输入如下URL:

http://127.0.0.1:5000/blog/整型参数
http://127.0.0.1:5000/rev/浮点型参数

传递HTTP请求

在计算机应用中,HTTP协议是互联网中数据通信的基础,各位读者需要熟悉使用的HTTP方法只有两种:GET与POST。在Flask框架中,默认使用的方法是GET方法,通过使用URL装饰器传递”方法类型“参数的方式的方式,可以让同一个URL同时处理两种请求方法。

from flask import Flask, request


html_txt = """<html>
    <body>
        <h2>如果收到了get请求</h2>
        <form method='post'>
            <input type='submit' value='按下我发送post请求' />
        </form>
    </body>
</html>
"""
app = Flask(__name__)
@app.route('/hello', methods=['GET', 'POST'])
def hello():
    if request.method == 'GET':
        return html_txt
    else:
        return '<h2>我已经接受到了post请求</h2>'


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

上面的程序,都是在同一个URL中实现POST请求和GET请求。另外,Flask框架可以使用url_for()来指定URL。

方法url_for()可以传递两个参数:

  • endpoint:表示将要传递的函数名
  • **values:是关键字参数,即有多个key=value的形式参数,对应URL中的变量部分。
from flask import Flask, redirect, url_for
app = Flask(__name__)


@app.route('/admin')
def hello_admin():
    return '你好,管理员'

@app.route('/guest/<guest>')
def hello_guest(guest):
    return '你好%s,你是游客' % guest

@app.route('/user/<name>')
def hello_user(name):
    if name == 'admin':
        return redirect(url_for('hello_admin'))
    else:
        return redirect(url_for('hello_guest', guest=name))


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

在上述代码中,在浏览器输入http://127.0.0.1:5000/user/admin,URL将重定向到http://127.0.0.1:5000/admin,执行函数hello_admin()的功能;如果接收的参数不是admin,则会将URL重定向到http://127.0.0.1:5000/guest/参数,执行函数hello_guest()的功能。

模拟实现用户登录系统

编写表单login.html,功能是实现静态HTML表单,表单中可以输入名字,点击提交按钮之后会使用POST方法将表单中的数据发送到指定的URL:http://127.0.0.1:5000/login

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="http://127.0.0.1:5000/login" method="post">
        <p>请输出命名</p>
        <p><input type="text" name="username" /></p>
        <p><input type="submit" value="登录"></p>
    </form>
</body>
</html>

接下来编写login.py,因为,当提交表单的时候,会映射到login()函数。因为服务器通过POST方法接收数据,因此可以通过下面的代码获取传递过来的参数username表单的值。

request.form.get('username')

服务器代码,如下所示:

from flask import Flask, redirect, request, url_for



app = Flask(__name__)
@app.route('/success/<name>')
def success(name):
    return '欢迎%s' % name + '登录本系统'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        user = request.form.get('username')
        print(user)
        return redirect(url_for('success', name=user))
    else:
        # return '请登录'
        user = request.form['username']
        return redirect(url_for('success', name=user))


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

点击登录之后,codings便会作为参数,被作为参数传递给/success/后面的参数name。