Flask简介
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。
“微”(micro) 并不表示你需要把整个 Web 应用塞进单个 Python 文件(虽然确实可以 ),也不意味着 Flask 在功能上有所欠缺。微框架中的“微”意味着 Flask 旨在保持核心简单而易于扩展。Flask 不会替你做出太多决策——比如使用何种数据库。而那些 Flask 所选择的——比如使用何种模板引擎——则很容易替换。除此之外的一切都由可由你掌握。如此,Flask 可以与您珠联璧合。
默认情况下,Flask 不包含数据库抽象层、表单验证,或是其它任何已有多种库可以胜任的功能。然而,Flask 支持用扩展来给应用添加这些功能,如同是 Flask 本身实现的一样。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。Flask 也许是“微小”的,但它已准备好在需求繁杂的生产环境中投入使用。
使用前需要下载
pip3 install flask
werkzeug
在django中我们使用WSGIREF模块来帮我们处理http请求,flask本身也没有提供socket服务和http请求的处理,这里使用Werkzeug模块,也是基于WSGI协议
from werkzeug.wrappers import Request, Response from werkzeug.serving import run_simple @Request.application def hello(request): return Response('Hello World!') if __name__ == '__main__': # 请求一旦到来,执行第三个参数 参数() run_simple('localhost', 4000, hello) # hello(xxx)
可以看到使用run_simple来运行服务,当有请求来时会将run_simple的第三个参数加括号执行
基本使用
from flask import Flask app = Flask(__name__) # 一个Flask类的对象 @app.route('/index') def index(): return 'Hello World' if __name__ == '__main__': app.run() # run_simple(host,port,app)
使用时我们先导入Flask,然后通过这个类来实例化一个对象app,接着我们定义我们的视图函数index,在django中我们会设置一个路由来对应这个视图函数,flask中也一样,只是设置时我们采用装饰器的形式@app.route('/index')
启动时采用app.run(),查看run的源码可以发现
本质上这还是在调用run_simple方法,而这个方法的第三个参数self就是app,所以这里实际上执行的是app(),也就是Flask类中的__call__方法,这里就是flask的入口
使用flask完成简单的登录注销功能
from flask import Flask, render_template, request, redirect, session app = Flask(__name__) # 一个Flask类的对象 app.secret_key = 'u2jksidjflsduwerjl' app.debug = True USER_DICT = { '1': {'name': '志军', 'age': 18}, '2': {'name': '大伟', 'age': 48}, '3': {'name': '梅凯', 'age': 38}, } @app.route('/login', methods=['GET', "POST"]) def login(): if request.method == 'GET': return render_template('login.html') user = request.form.get('user') # 获取POST传过来的值 pwd = request.form.get('pwd') # 获取POST传过来的值 if user == 'alex' and pwd == '123': # 用户信息放入session session['user_info'] = user return redirect('/index') else: return render_template('login.html', msg='用户名或密码错误') # return render_template('login.html',**{'msg':'用户名或密码错误'}) @app.route('/index', endpoint='n1') def index(): user_info = session.get('user_info') if not user_info: return redirect('/login') return render_template('index.html', user_dict=USER_DICT) @app.route('/detail') def detail(): user_info = session.get('user_info') if not user_info: return redirect('/login') uid = request.args.get('uid') info = USER_DICT.get(uid) return render_template('detail.html', info=info) @app.route('/logout') def logout(): del session['user_info'] return redirect('/login') if __name__ == '__main__': app.run()
login函数
当用户get请求访问时,我们需要返回给用户一个登录页面,在django中我们使用render来渲染页面,在flask中我们仿照django来找找看,发现可以导入一个render_template,在给用户返回页面时我们使用它,而login.html应该放在哪里呢,我们还是模仿django,
创建一个templates目录,将login.html放在里面
这样给用户返回时就可以使用下面的方式了
@app.route('/login', methods=['GET', "POST"]) def login(): if request.method == 'GET': return render_template('login.html')
用户看到页面后,开始登录,输入了用户名密码后,点击登录,会向后台发送post请求,这里要注意,在flask中默认只同意GET请求,当POST求情发送过来时是无法进入视图函数的,所以我们需要在设置路由时加上methods参数,使POST请求可以被通过,PUT,
DELETE等请求同理
@app.route('/login', methods=['GET', "POST"])
视图函数中收到用户的post请求后,需要取到用户名密码进行验证,在django的视图函数中会传一个request参数,从request中我们可以获取想要的数据,而flask的视图函数并没有传参,我们需要去导入request,然后获取数据
request.form # 获取POST请求的数据 request.args # 获取GET请求的数据
拿到数据如果用户名密码正确则要将信息写入session,并跳转首页,如果不正确则要将错误信息在页面上显示
from flask import Flask, render_template, request, redirect, session app = Flask(__name__) # 一个Flask类的对象 app.secret_key = 'u2jksidjflsduwerjl' app.debug = True @app.route('/login', methods=['GET', "POST"]) def login(): if request.method == 'GET': return render_template('login.html') user = request.form.get('user') # 获取POST传过来的值 pwd = request.form.get('pwd') # 获取POST传过来的值 if user == 'alex' and pwd == '123': # 用户信息放入session session['user_info'] = user return redirect('/index') else: return render_template('login.html', msg='用户名或密码错误') # return render_template('login.html',**{'msg':'用户名或密码错误'})
需要注意的是,在django中设置session时默认会将session数据写入数据库,而在这里,我们并没有涉及数据库,flask默认会将session的数据写到COOKIE中,如果不加密,这样太不安全了,所以这里我们需要对session进行加密app.secret_key = 'u2jksidjflsduwerjl',这是设置加密的加盐字符串,如果不设置直接设置session会报错
在跳转时和django一样使用redirect(同样需要导入),如果不正确需要再次返回页面,不过这次需要将错误信息显示到页面上,这里传递参数时和django有些不同,页面渲染基本一样
<body> <h1>登录</h1> <form method="post"> <input type="text" name="user"> <input type="password" name="pwd"> <input type="submit" value="提交"> {{msg}} </form> </body>
index函数
@app.route('/index', endpoint='n1') def index(): user_info = session.get('user_info') if not user_info: return redirect('/login') return render_template('index.html', user_dict=USER_DICT)
index中先利用session判断用户是否登录,如果没有则跳转登录页面,如果登录了则返回首页的页面,这里我们没有从数据库中取数据,而是写好了一个USER_DICT的字典来模拟数据库中的数据,渲染时和django基本相同
<body> <ul> {% for k,v in user_dict.items() %} <li>{{v.name}} <a href="/detail?uid={{k}}">查看详细</a></li> {% endfor %} </ul> </body>
这里的endpoint参数是函数的别名
detail函数
@app.route('/detail') def detail(): user_info = session.get('user_info') if not user_info: return redirect('/login') uid = request.args.get('uid') info = USER_DICT.get(uid) return render_template('detail.html', info=info)
这里使用request.args获取GET请求的数据
logout函数
@app.route('/logout') def logout(): del session['user_info'] return redirect('/login')
注销时删除session中的值即可,session操作就是字典操作