一、Flask教程
Flask是一个免费的web框架,也是一个年轻、充满活力的小型框架,开发文档齐 全,社区活跃度高,有着众多支持者。
Flask的设计目标是实现一个WSGI的微框架, 其核心代码十分简单。 Flask框架在中小型企业中的占有率比较高web框架,一般是用于开发轻量级web应 用程序,Flask框架在市场占用率来说排名也是比较靠前的。本文主要介绍的内容是 Flask框架的基本知识,包括它的基本结构以及它与Django框架的对比。
Flask框架的基本结构图,如下所示:
为了提高开发效率,减少冗余的代码,Flask框架会抽出web开发中的共同部分,以 便在不同的页面中多次使用该部分。当客户端想要从web服务器中获取某些信息数据 时,便会发起一个HTTP请求(例如,我们平时在浏览器中输入一个URL),Web应用 会在后台,进行相应的业务处理(例如,读取数据库或者进行一些计算),然后读取 用户需要的数据,生成相应的HTTP响应。如果访问的是静态资源,那么直接返回资 源即可,不需要进行业务操作。
二、Flask安装
使用以下指令安装:
pip install flask
安装成功后,输入指令可以查看到版本
import flask print(flask.__version__)
三、最小的应用
【步骤】:
- 导入Flask包
- 创建一个Flask对象
- 声明路由,在路由下面写想要展示出的内容
- 使用Flask 的run()方法在本地的服务器上运行应用程序;
为了测试 Flask 安装,请在编辑器中将以下代码输入 至一个py文件:
from flask import Flask # 必须在项目中导入Flask模块。 # 创建一个Flask的对象 app = Flask(__name__) # Flask类的一个对象是我们的WSGI应用程序。Flask构造函数使用当前模块(__name __)的名称作为参数。 # 声明路由; 必须以斜杠开头 @app.route('/') def hello_world(): return '<h1>Hello World</h1>' @app.route('/index') def hello_world2(): return '<h1>Hello World2</h1>' if __name__ == '__main__': app.run()
请求的端口是什么?就是你请求的ip端口后面的以斜杠开头的内容,在请求ip后面不加路由默认是/
Flask类的route()函数是一个装饰器,它告诉应用程序哪个URL应该调用相关的函数。
app.route(rule, options)
- rule 参数表示与该函数的URL绑定。
- options 是要转发给基础Rule对象的参数列表。
在上面的示例中,'/ ' URL与hello_world()函数绑定,'/index ' URL与hello_world2()函数绑定。
因此,当在浏览器中打开web服务器的主页时,将呈现该函数的输出。
最后,Flask类的run()方法在本地开发服务器上运行应用程序。
app.run(host, port, debug, options)
修改一下app.run()的参数
from flask import Flask # 必须在项目中导入Flask模块。 # 创建一个Flask的对象 app = Flask(__name__) # Flask类的一个对象是我们的WSGI应用程序。Flask构造函数使用当前模块(__name __)的名称作为参数。 # 声明路由; 必须以斜杠开头 @app.route('/') def hello_world(): return '<h1>Hello World</h1>' @app.route('/index') def hello_world2(): return '<h1>Hello World2</h1>' if __name__ == '__main__': app.run(host='192.168.*.*', port=5001, debug=True)
修改成功后,可以访问修改过的ip
【注意】 ip不能随便乱写,按Win+R键,输入cmd,进入界面后输入ipcoonfig来查看ip
四、处理URL参数
在web程序中,URL并不一定是静止不变的,可能会存在动态的情况,需要在对应处 理函数中的列表参数声明变量名。
from flask import Flask app = Flask(__name__) @app.route('/hello/<name>') def hello(name): return '你好 %s' % name if __name__ == '__main__': app.run(debug=True)
在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']) # 输入路由后,默认是GET请求 def hello(): if request.method == 'GET': return html_txt else: return '<h2>我已经接受到了post请求</h2>' if __name__ == '__main__': app.run(debug=True)
默认是GET请求:
点击按钮后:
上面的程序,都是在同一个URL中实现POST请求和GET请求。
redirect()方法可以实现重定向
输入/user/admin 按下回车会跳转到/admin路由from flask import Flask, request, 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('/admin') # redirect()实现重定向,如果输入的参数等于admin、,则重定向到/admin路由下,否则重定向到/guest下 else: return redirect('/guest/<guest>') if __name__ == '__main__': app.run(debug=True)
输入/user/guest/123
按下回车会跳转到/guest<guest>界面
但是你会发现一个问题,虽然跳转过来了,但是你想传递的参数123没有传递过去,这时候可以使用url_for()方法,它只会跳转到指定界面,并且将参数传递过去;
另外,Flask框架可以 使用 url_for() 来指定URL。
方法 url_for() 可以传递两个参数:
- endpoint:表示将要传递的函数名
- values:是关键字参数,即有多个key=value的形式参数,对应URL中的变量部 分。
from flask import Flask, request, 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))
参数传递成功:
在上述代码中,在浏览器输入 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()的功能。
六、模拟实现用户登录系统
from flask import Flask, request, redirect, url_for app = Flask(__name__) html_text = '''<!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, initialscale=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="password" name="password" /></p> <p><input type="submit" value="登录"></p> </form> </body> </html> ''' @app.route('/success/<name>') def success(name): return '欢迎%s' % name + '登录本系统' @app.route('/') def index(): return html_text @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': user = request.form.get('username') # 通过html页面的input标签中的name属性拿值,所以此处的值必须和input标签中的name属性值一致 password = request.form.get('password') # print(user) # print(password) inner_user_password = {'user': 'Admin', 'password': '123'} if user == inner_user_password['user'] and password == inner_user_password['password']: print('登录成功') return redirect(url_for('success', name=user)) else: return '<p>您输入的用户名和密码错误</p>' if __name__ == '__main__': app.run(debug=True)
输入正确账号密码:
点击登录之后,Admin 便会作为参数,被作为参数传递给/success/后面的参数 name。
输入错误的账号和密码:
更好看的页面from flask import Flask, request, redirect, url_for app = Flask(__name__) html_text = ''' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } a { text-decoration: none; } input, button { background: transparent; border: 0; outline: none; } body { height: 100vh; background: linear-gradient(#141e30, #243b55); display: flex; justify-content: center; align-items: center; font-size: 16px; color: #03e9f4; } .loginBox { width: 400px; height: 364px; background-color: #0c1622; margin: 100px auto; border-radius: 10px; box-shadow: 0 15px 25px 0 rgba(0, 0, 0, .6); padding: 40px; box-sizing: border-box; } h2 { text-align: center; color: aliceblue; margin-bottom: 30px; font-family: 'Courier New', Courier, monospace; } .item { height: 45px; border-bottom: 1px solid #fff; margin-bottom: 40px; position: relative; } .item input { width: 100%; height: 100%; color: #fff; padding-top: 20px; box-sizing: border-box; } .item input:focus+label, .item input:valid+label { top: 0px; font-size: 2px; } .item label { position: absolute; left: 0; top: 12px; transition: all 0.5s linear; } .btn { padding: 10px 20px; margin-top: 30px; color: #03e9f4; position: relative; overflow: hidden; text-transform: uppercase; letter-spacing: 2px; left: 35%; } .btn:hover { border-radius: 5px; color: #fff; background: #03e9f4; box-shadow: 0 0 5px 0 #03e9f4, 0 0 25px 0 #03e9f4, 0 0 50px 0 #03e9f4, 0 0 100px 0 #03e9f4; transition: all 1s linear; } .btn>span { position: absolute; } .btn>span:nth-child(1) { width: 100%; height: 2px; background: -webkit-linear-gradient(left, transparent, #03e9f4); left: -100%; top: 0px; animation: line1 1s linear infinite; } @keyframes line1 { 50%, 100% { left: 100%; } } .btn>span:nth-child(2) { width: 2px; height: 100%; background: -webkit-linear-gradient(top, transparent, #03e9f4); right: 0px; top: -100%; animation: line2 1s 0.25s linear infinite; } @keyframes line2 { 50%, 100% { top: 100%; } } .btn>span:nth-child(3) { width: 100%; height: 2px; background: -webkit-linear-gradient(left, #03e9f4, transparent); left: 100%; bottom: 0px; animation: line3 1s 0.75s linear infinite; } @keyframes line3 { 50%, 100% { left: -100%; } } .btn>span:nth-child(4) { width: 2px; height: 100%; background: -webkit-linear-gradient(top, transparent, #03e9f4); left: 0px; top: 100%; animation: line4 1s 1s linear infinite; } @keyframes line4 { 50%, 100% { top: -100%; } } </style> </head> <body> <div class="loginBox"> <h2>login</h2> <form action="http://127.0.0.1:5000/login" method="post"> <div class="item"> <input type="text" required name="username"> <label for="">用户名</label> </div> <div class="item"> <input type="password" required name="password"> <label for="">密码</label> </div> <button class="btn">登录 <span></span> <span></span> <span></span> <span></span> </button> </form> </div> </body> </html> ''' @app.route('/success/<name>') def success(name): return '欢迎%s' % name + '登录本系统' @app.route('/') def index(): return html_text @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': user = request.form.get('username') # 通过html页面的input标签中的name属性拿值,所以此处的值必须和input标签中的name属性值一致 password = request.form.get('password') # print(user) # print(password) inner_user_password = {'user': 'Admin', 'password': '123'} if user == inner_user_password['user'] and password == inner_user_password['password']: print('登录成功') return redirect(url_for('success', name=user)) else: return '<p>您输入的用户名和密码错误</p>' if __name__ == '__main__': app.run(debug=True)