关于响应处理

1 序列化数据

Flask-RESTful 提供了marshal工具,用来帮助我们将数据序列化为特定格式的字典数据,以便作为视图的返回值。

  1. from flask_restful import Resource, fields, marshal_with
  2. resource_fields = {
  3. 'name': fields.String,
  4. 'address': fields.String,
  5. 'user_id': fields.Integer
  6. }
  7. class Todo(Resource):
  8. @marshal_with(resource_fields, envelope='resource')
  9. def get(self, **kwargs):
  10. return db_get_todo()

也可以不使用装饰器的方式

  1. class Todo(Resource):
  2. def get(self, **kwargs):
  3. data = db_get_todo()
  4. return marshal(data, resource_fields)

示例

  1. # 用来模拟要返回的数据对象的类
  2. class User(object):
  3. def __init__(self, user_id, name, age):
  4. self.user_id = user_id
  5. self.name = name
  6. self.age = age
  7. resoure_fields = {
  8. 'user_id': fields.Integer,
  9. 'name': fields.String
  10. }
  11. class Demo1Resource(Resource):
  12. @marshal_with(resoure_fields, envelope='data1')
  13. def get(self):
  14. user = User(1, 'itcast', 12)
  15. return user
  16. class Demo2Resource(Resource):
  17. def get(self):
  18. user = User(1, 'itcast', 12)
  19. return marshal(user, resoure_fields, envelope='data2')

2 定制返回的JSON格式

需求

想要接口返回的JSON数据具有如下统一的格式

  1. {"message": "描述信息", "data": {要返回的具体数据}}

在接口处理正常的情况下, message返回ok即可,但是若想每个接口正确返回时省略message字段

  1. class DemoResource(Resource):
  2. def get(self):
  3. return {'user_id':1, 'name': 'itcast'}

对于诸如此类的接口,能否在某处统一格式化成上述需求格式?

  1. {"message": "OK", "data": {'user_id':1, 'name': 'itcast'}}

解决

Flask-RESTful的Api对象提供了一个representation的装饰器,允许定制返回数据的呈现格式

  1. api = Api(app)
  2. @api.representation('application/json')
  3. def handle_json(data, code, headers):
  4. # TODO 此处添加自定义处理
  5. return resp

Flask-RESTful原始对于json的格式处理方式如下:
代码出处:flask_restful.representations.json

  1. from flask import make_response, current_app
  2. from flask_restful.utils import PY3
  3. from json import dumps
  4. def output_json(data, code, headers=None):
  5. """Makes a Flask response with a JSON encoded body"""
  6. settings = current_app.config.get('RESTFUL_JSON', {})
  7. # If we're in debug mode, and the indent is not set, we set it to a
  8. # reasonable value here. Note that this won't override any existing value
  9. # that was set. We also set the "sort_keys" value.
  10. if current_app.debug:
  11. settings.setdefault('indent', 4)
  12. settings.setdefault('sort_keys', not PY3)
  13. # always end the json dumps with a new line
  14. # see https://github.com/mitsuhiko/flask/pull/1262
  15. dumped = dumps(data, **settings) + "\n"
  16. resp = make_response(dumped, code)
  17. resp.headers.extend(headers or {})
  18. return resp

为满足需求,做如下改动即可

  1. @api.representation('application/json')
  2. def output_json(data, code, headers=None):
  3. """Makes a Flask response with a JSON encoded body"""
  4. # 此处为自己添加***************
  5. if 'message' not in data:
  6. data = {
  7. 'message': 'OK',
  8. 'data': data
  9. }
  10. # **************************
  11. settings = current_app.config.get('RESTFUL_JSON', {})
  12. # If we're in debug mode, and the indent is not set, we set it to a
  13. # reasonable value here. Note that this won't override any existing value
  14. # that was set. We also set the "sort_keys" value.
  15. if current_app.debug:
  16. settings.setdefault('indent', 4)
  17. settings.setdefault('sort_keys', not PY3)
  18. # always end the json dumps with a new line
  19. # see https://github.com/mitsuhiko/flask/pull/1262
  20. dumped = dumps(data, **settings) + "\n"
  21. resp = make_response(dumped, code)
  22. resp.headers.extend(headers or {})
  23. return resp