Flask目录:https://www.jianshu.com/p/9b5e30320849
路由
路由充当了一个指路牌的作用,让用户访问想要访问的页面得到想要的数据。
路由
当然也可以多个页面指向同一个路由(不过这样肯定是有关联的页面,最好使用正则URL)
路由配置
Flask的路由配置是没有专门的文件存放的,基本是以装饰器的形式存在视图函数顶部。
实例:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
#路由装饰器,语法为 app.route(url_name,methods)
#url_name:路由名
#methods:请求方式,默认get请求,可以使用列表指定多种方式。例:['GET','POST']
@app.route('/index')
def hi_flask():
return 'Hi,Flask'
if __name__ == '__main__':
app.run()
页面截图
同时,路由也有多种写法:
参数传递:@app.route('/users/<username>')
指定类型:@app.route('/users/<int:pwd>')
参数类型表
一个简单的传参请求
实例:
from flask import Flask,url_for
app = Flask(__name__)
#使用参数接受url
@app.route('/user/<username>')
#给username设置一个默认值,这样不输入username也可以访问到这个页面。
def users(username=''):
return "用户名:{}".format(username)
if __name__ == '__main__':
app.run()
页面截图
同时还有另外一种方式,就是API方式。
实例:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
def hi_flask2():
return 'Hi,Flask2'
app.add_url_rule("/index2/", view_func=hi_flask2)
#API函数,第一个参数是路由名,第二个参数要以关键字参数传入,值是一个配套的函数名。
if __name__ == '__main__':
app.run()
页面截图
这两种方式的详解
首先我们从装饰器入手:
源码如下
-------
def route(self, rule, **options):
"""A decorator that is used to register a view function for a
given URL rule. This does the same thing as :meth:`add_url_rule`
but is intended for decorator usage::
@app.route('/')
def index():
return 'Hello World'
For more information refer to :ref:`url-route-registrations`.
:param rule: the URL rule as string
:param endpoint: the endpoint for the registered URL rule. Flask
itself assumes the name of the view function as
endpoint
:param options: the options to be forwarded to the underlying
:class:`~werkzeug.routing.Rule` object. A change
to Werkzeug is handling of method options. methods
is a list of methods this rule should be limited
to (``GET``, ``POST`` etc.). By default a rule
just listens for ``GET`` (and implicitly ``HEAD``).
Starting with Flask 0.6, ``OPTIONS`` is implicitly
added and handled by the standard request handling.
"""
def decorator(f):
endpoint = options.pop("endpoint", None)
self.add_url_rule(rule, endpoint, f, **options)
#这里调用了add_url_rule
return f
return decorator
也就是说,route只不过是封装了一下的装饰器,干活的还是add_url_rule。
这样的话,大家直接用装饰器就好了。
路由反向解析
说到路由,就不能不能不说路由的反向解析,他可以帮助我们获得用户请求的路由与配套的视图函数。
实例:
from flask import Flask,url_for
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
#路由装饰器, 语法为 app.route(url_name,method) 前者是路由名, 后者是请求方式,默认get请求
@app.route('/index')
def hi_flask():
return 'Hi,Flask'
def hi_flask2():
return 'Hi,Flask2'
app.add_url_rule("/index2/", view_func=hi_flask2)
#API函数,第一个参数是路由名,第二个参数要以关键字参数传入,值是一个配套的函数名。
# 查看URL规则
print(app.url_map)
# 反向解析,通过视图名找到对应的路由
with app.test_request_context():
print(url_for('hello_world'))
print(url_for('hi_flask2'))
if __name__ == '__main__':
app.run()
输出结果:
--------
Map([<Rule '/index2/' (GET, OPTIONS, HEAD) -> hi_flas2k>,
<Rule '/index' (GET, OPTIONS, HEAD) -> hi_flask>,
<Rule '/' (GET, OPTIONS, HEAD) -> hello_world>,
<Rule '/static/<filename>' (GET, OPTIONS, HEAD) -> static>])
/
/index2/
当然 url_for()还有很多其他的功能,以后会慢慢说。
请求与响应
上下文
上下文分为,请求上下文与应用上下文。用语文中的概念来理解即可。在计算机中,可以把它理解为环境。
引用上下文
current_app:当前应用的案例
g:处理请求时的临时存储对象,每次请求都会重设这个对象
请求上下文
request:请求对象,封装了客户端发给服务端的HTTP请求
session:用户会话,在各个会话中共享数据
请求
请求分派
请求分派我们来了一个请求'/index/',那么这个请求该去找哪个url规则呢,这个让请求找到他目的地的过程就是请求分派。
请求报文常用参数
method:请求的方式(get,post等等)
args:get请求提交的数据
form:form表单提交的数据
files:文件上传
cookies:cookie的传输
headers:HTTP请求头
GET请求
from flask import Flask,request
app = Flask(__name__)
@app.route('/user')
def users():
#request是获取用户请求对象,args是获取用户get请求数据 数据是dict类型。
get_dict = request.args
print(get_dict)
#从数据集中获取某一个值。
username = request.args.get('username')
print(username)
#既然是dict类型,还是get方法,肯定能设置默认值啦。
page = request.args.get('page',1)
print(page)
return "用户名:{}".format(username)
if __name__ == '__main__':
app.run()
----------
输出结果:
ImmutableMultiDict([('username', 'lisi')])
lisi
1
image.png
POST请求
在将模板操作时一起说。
请求头
headers是一个字典类型的数据,获取后还可以通过get函数得到我们想要的数据,例如请求的ip,系统平台等等。
from flask import Flask,request
app = Flask(__name__)
@app.route('/user')
def users():
headers = request.headers
return "请求头:{}".format(headers)
if __name__ == '__main__':
app.run()
请求头
请求钩子
请求钩子就是用来校验用户请求舒服是否合法。有四个常用函数
- before_first_request
服务器初始化后第一个请求到达前执行 - before_request
每一个请求到达前执行 - after_request
每次请求处理完成后执行,如果请求过程中产生了日常,则不执行。 - teardown_request
每次请求处理完成后执行,如果请求过程中发生了异常也执行。
实例1:
from flask import Flask,request
app = Flask(__name__)
@app.before_first_request
def first_req():
print('first_request')
print('------')
@app.before_request
def before_req():
print('brfore_request')
print('------')
@app.route('/user')
def users():
get_dict = request.args
print(get_dict)
print('------')
return "请求参数:{}".format(get_dict)
if __name__ == '__main__':
app.run()
请求前
before_first_request函数确实只在确认连接的时候认证一次,而before_request会对每一次连接进行认证。
实例2:
from flask import Flask,request
app = Flask(__name__)
@app.before_first_request
def first_req():
print('first_request')
print('------')
@app.before_request
def before_req():
print('brfore_request')
print('------')
@app.after_request
def after_req(resp):
print('after_request')
print('------')
return resp
@app.route('/user')
def users():
get_dict = request.args
print(get_dict)
print('------')
return "请求参数:{}".format(get_dict)
if __name__ == '__main__':
app.run()
输出结果
只要请求内部不报错, after_request就会完美执行。
teardown_request可以作为一个异常处理的方法,我们这里不探究他的使用。
响应
我们处理完用户的请求,反馈给用户的数据就是响应。响应可以是各种数据。其中特殊的包括我们反馈的数据,页面,状态码和响应头。
404
我们请求一个不存在的页面,肯定会得到404的状态码。但是我们不想返回这个朴素的页面,这就需要我们的响应定制了。
from flask import Flask,request
app = Flask(__name__)
@app.errorhandler(404)
def not_fount(err):
print(err)
return '你要找的页面找不到了'
if __name__ == '__main__':
app.run()
自定义404
同时我们也可以修改一下返回的数据,例如状态码或者headers。
@app.errorhandler(404)
def not_fount(err):
print(err)
return '你要找的页面找不到了',404,{
'is_login':False
}
自定义404
接着来看响应经常用到的方法:
make_response():相当于Django中的HttpResponse。
from flask import Flask,make_response
app = Flask(__name__)
@app.route('/test')
def test():
make = make_response("<h1>这是一个测试页面</h1>",200)
return make
if __name__ == '__main__':
app.run()
make_response
但是一般我们都是返回一个页面的:
from flask import Flask,make_response,render_template
app = Flask(__name__)
@app.route('/test')
def test():
tmp = render_template('index.html')
make = make_response(tmp,200)
return make
if __name__ == '__main__':
app.run()
render_template
make_response 想要返回页面,不能直接写做:make_response('hello.html'),必须用render_template('hello.html')形式。
重定向
redirect():相当于 Django中的HttpResponseRedirect。
from flask import Flask,make_response
app = Flask(__name__)
@app.route('/test')
def test():
make = make_response("<h1>这是一个测试页面</h1>",200)
return make
@app.route('/test1')
def test1():
return redirect('/test')
if __name__ == '__main__':
app.run()
redirect
同时还有一个中止重定向的函数:
abort()函数用于提前退出一个请求,并用指定的错误码返回。
from flask import Flask,make_response
app = Flask(__name__)
@app.route('/test')
def test():
make = make_response("<h1>这是一个测试页面</h1>",200)
return make
@app.route('/test1')
def test1():
headers = request.headers
ip = headers.get('host')
print(ip)
ip_list = ['127.0.0.1:5000']
if ip in ip_list:
abort(403)
return redirect('/test')
if __name__ == '__main__':
app.run()
我们这里模仿了一个ip请求黑白名单的访问。如果请求ip是我们的黑名单ip,就抛出一个403请求中断当前请求。
abort
网友评论