1、Flask的上下文
flask上下文请求就是当一个flask项目被多次请求的时候,为了保证用户请求的隔离性,知道是谁发送的请求数据,
Flask项目中有两个上下文,一个是应用上下文(app),另外一个是请求上下文
(request)。请求上下文request和应用上下文current_app都是一个全局变量。所有请求都共享的。Flask有特殊的机制可以保证每次请求的数据都是隔离的,即A请求所产生的数据不会影响到B请求。所以可以直接导入request对象,也不会被一些脏数据影响了,并且不需要在每个函数中使用request的时候传入request对象。这两个上下文具体的实现方式和原理可以没必要详细了解。
request:请求上下文上的对象。这个对象一般用来保存一些请求的变量。比如method、args、form等。
session:请求上下文上的对象。这个对象—般用来保存一些会话信息。. current_app:返回当前的app。要写在视图里面或者写在with文件资源管理器中
g:应用上下文上的对象。处理请求时用作临时存储的对象。
2、钩子函数
from flask import Flask, render_template,abort
app = Flask(__name__)
@app.route('/') # 第三个被执行
def index():
abort(404) # 直接让首页抛出异常,404去接受
print('这是首页')
return '这是首页'
@app.before_first_request # 第一个被执行
def handel_first_request():
print('这是第一次请求之前执行的')
@app.before_request # 第二个被执行
def handel_before():
print('每次请求之前被执行的')
@app.after_request # 第四个被执行
def handel_after(response):
print('每次请求之后执行的')
return response
@app.teardown_appcontext # 第五个被执行不管是否有异常,注册的函数都会在每次请求之后执行。
def handel_teardown(response):
print('handel_teardown被执行了')
return response
@app.context_processor # 直接映射到了所有的模板中,不用一个一个的写内容去映射
def context_processor():
return {'current_user': 'xxx'}
@app.errorhandler(404)
def page_not_found(error):
return 'This page does not exist', 404
@app.errorhandler(500)
def page_not_found(error):
# return 'This page does not exist', 500
return render_template('index.html'),500
if __name__ == '__main__':
app.run(debug=True)
3、Restful API规范
Restful API规范
①定义:restful api是用于在前端与后台进行通信的一套规范。使用这个规范可以让前后端开发变得更加轻松。以下将讨论这套规范的一些设计细节。
②协议:采用http或者https协议。
③数据传输格式:数据之间传输的格式应该都使用json,而不使用xml。
④HTTP请求的方法
GET: 从服务器上获取资源。
POST: 在服务器上新创建一 个资源。
PUT:在服务器上更新资源。 (客户端提供所有改变后的数据)
PATCH: 在服务器上更新资源。 (客户端只提供需要改变的属性)
DELETE:从服务器上删除资源。
⑤状态码的介绍
4、Flask-Restful插件
①Flask-Restful是一个专门用来写restful api的一个插件。它可以快速的集成restful api功能。在app的后台以及纯api的后台中,这个插件可以帮助我们节省很多时间。当然,如果在普通的网站中,这个插件就显得有些鸡肋了,因为在普通的网页开发中,是需要去渲染HTML代码的,而Flask-Restful在每 个请求中都是返回json格式的数据。
②Flask-Restful需要在Flask 0.8以上的版本,在Python2.6或者Python3.3. 上运行。通过pipinstall flask-restful即可安装。
from flask import Flask, render_template, url_for
from flask_restful import Api, Resource, reqparse,inputs
app = Flask(__name__)
# 用Api来绑定app
api = Api(app)
class IndexView(Resource):
def get(self):
return {"username": "juran"}
def post(self):
parse = reqparse.RequestParser()
# 字段名,类型,错误信息,是否必须传入
parse.add_argument('username', type=str, help='用户名验证错误', requires=True)
parse.add_argument('gender', type=str, help='用户名验证错误', requires=True,choices=['male','secret','female'])
parse.add_argument('gender', type=inputs.url_regex, help='地址错误', requires=True)
parse.add_argument('phone', type=inputs.regex(r'1[358]\d{9}'), help='手机号错误', requires=True)
args = parse.parse_args()
# email url regex 要通过inputs导入
print(args) # 可以接受到前端传过来的参数,传过来的是一个字典
return {'info': '登录成功'}
api.add_resource(IndexView, '/', endpoint='index')
if __name__ == '__main__':
app.run(debug=True)
default:默认值,如果这个参数没有值,那么将使用这个参数指定的值。
required:是否必须。默认为False,如果设置为True,那么这个参数就必须提交上来。
type:这个参数的数据类型,如果指定,那么将使用指定的数据类型来强制转换提交上来的值。
choices:提交上来的值只有满足这个选项中的值才符合验证通过,否则验证不通过。
help:错误信息。如果验证失败后,将会使用这个参数指定的值作为错误信息。
trim:是否要去掉前后的空格。
4.1输出字段
对于一个视图函数,可以指定好一些字段用于返回。 以后可以使用ORM模型或者自定义的模型的时候,他会自动的获取模型中的相应的字段,生成json数据, 然后再返回给客户端。这其中需要导入flask _restful.marshal. with装饰器。并且需要写一个字典,来指示需要返回的字段,以及该字段的数据类型。
from flask import Flask, render_template, url_for
from flask_restful import Api, Resource, reqparse,inputs,fields,marshal_with
app = Flask(__name__)
# 用Api来绑定app
api = Api(app)
class ArticleView(Resource):
resource_fields = {
'title':fields.String,
'context':fields.String
}
# 即使这个参数没有值,也会返回,只不过返回的是空值
@marshal_with(resource_fields)
def get(self):
return {'title':'beiyue'}
api.add_resource(ArticleView,'/article/',endpoint='article')
if __name__ == '__main__':
app.run(debug=True)
4.2复杂结构的返回
import config
from flask import Flask
from exts import db
from flask_restful import Api,Resource,fields,marshal_with
from models import Article
app = Flask(__name__)
app.config.from_object(config)
db.init_app(app)
api = Api(app)
class ArticleView(Resource):
resource_fields = {
'id':fields.String,
'content':fields.String(attribute='content'),
# 如果模型中有这个字段而且数据库中有值,则default没用
'title':fields.String(default='1234'),
'users':fields.Nested({
'username':fields.String,
'email':fields.String
}),
'tags':fields.List(fields.Nested({
'id':fields.Integer,
'name':fields.String
})),
'read_count':fields.Integer(default=0)
}
# 即使这个参数没有值,也会返回,只不过返回的是空值
@marshal_with(resource_fields)
def get(self,article_id):
article = Article.query.get(article_id)
# return {'title':'beiyue'}
return article
api.add_resource(ArticleView,'/article/<article_id>',endpoint='article')
if __name__ == '__main__':
app.run(debug=True)