Flask-RESTful——格式化输出字段详解

一、flask-restful格式化输出字段

Flask-RESTful 提供了一个简单的方式来控制在你的响应中实际呈现什么数据。
使用 fields 模块,你可以使用在你的资源里的任意对象(ORM 模型、定制的类等等)
并且 fields 让你格式化和过滤响应,因此您不必担心暴露内部数据结构。

1、基本用法:装饰方法
from flask.ext.restful import Resource, fields, marshal_with

# 定义输出格式化字段
resource_fields = {
    'name': fields.String,
    'address': fields.String,
    'date_updated': fields.DateTime(dt_format='rfc822'),
}

class Todo(Resource):
	
	# 采用装饰器格式化
    @marshal_with(resource_fields, envelope='resource') 
    # marshal_with 能够在单个对象,字典,或者列表对象上工作。
    def get(self, **kwargs):
        return db_get_todo()  # 返回必须是对象
  '''
这个例子假设你有一个自定义的数据库对象(todo),它具有属性:name, address, 以及 date_updated。该对象上任何其它的属性可以被认为是私有的不会在输出中呈现出来。
一个可选的 envelope 关键字参数被指定为封装结果输出。
'''
2、响应重命名属性

很多时候你面向公众的字段名称是不同于内部的属性名。使用 attribute 可以配置这种映射。

fields = {
    'name': fields.String(attribute='private_name'),
    'address': fields.String,
}

lambda 也能在 attribute 中使用

fields = {
    'name': fields.String(attribute=lambda x: x._private_name),
    'address': fields.String,
}
3、返回默认值

如果由于某种原因你的数据对象中并没有你定义的字段列表中的属性,你可以指定一个默认值而不是返回 None。

fields = {
    'name': fields.String(default='Anonymous User'),
    'address': fields.String,
}
4、自定义字段&多个值

当一个属性存储多条信息的时候是特别有用的。

class UrgentItem(fields.Raw):
    def format(self, value):
        return "Urgent" if value & 0x01 else "Normal"

class UnreadItem(fields.Raw):
    def format(self, value):
        return "Unread" if value & 0x02 else "Read"

fields = {
    'name': fields.String,
    'priority': UrgentItem(attribute='flags'),
    'status': UnreadItem(attribute='flags'),
}
5、URI&其它具体字段

Flask-RESTful 包含一个特别的字段,fields.Url,即为所请求的资源合成一个 uri。

class RandomNumber(fields.Raw):
    def output(self, key, obj):
        return random.random()

fields = {
    'name': fields.String,
    # todo_resource is the endpoint name when you called api.add_resource()
    'uri': fields.Url('todo_resource'),
    'random': RandomNumber,
}

默认情况下,fields.Url 返回一个相对的 uri。
为了生成包含协议(scheme),主机名以及端口的绝对 uri,需要在字段声明的时候传入 absolute=True。传入 scheme 关键字参数可以覆盖默认的协议(scheme)

fields = {
    'uri': fields.Url('todo_resource', absolute=True)
    'https_uri': fields.Url('todo_resource', absolute=True, scheme='https')
}
6、复杂结构

你可以有一个扁平的结构,marshal_with 将会把它转变为一个嵌套结构

>>> from flask.ext.restful import fields, marshal
>>> import json
>>>
>>> resource_fields = {'name': fields.String}
>>> resource_fields['address'] = {}
>>> resource_fields['address']['line 1'] = fields.String(attribute='addr1')
>>> resource_fields['address']['line 2'] = fields.String(attribute='addr2')
>>> resource_fields['address']['city'] = fields.String
>>> resource_fields['address']['state'] = fields.String
>>> resource_fields['address']['zip'] = fields.String
>>> data = {'name': 'bob', 'addr1': '123 fake street', 'addr2': '', 'city': 'New York', 'state': 'NY', 'zip': '10468'}
>>> json.dumps(marshal(data, resource_fields))
'{"name": "bob", "address": {"line 1": "123 fake street", "line 2": "", "state": "NY", "zip": "10468", "city": "New York"}}'
7、列表字段

你也可以把字段解组(unmarshal)成列表

>>> from flask.ext.restful import fields, marshal
>>> import json
>>>
>>> resource_fields = {'name': fields.String, 'first_names': fields.List(fields.String)}
>>> data = {'name': 'Bougnazal', 'first_names' : ['Emile', 'Raoul']}
>>> json.dumps(marshal(data, resource_fields))
>>> '{"first_names": ["Emile", "Raoul"], "name": "Bougnazal"}'
8、嵌套字段
>>> from flask.ext.restful import fields, marshal
>>> import json
>>>
>>> address_fields = {}
>>> address_fields['line 1'] = fields.String(attribute='addr1')
>>> address_fields['line 2'] = fields.String(attribute='addr2')
>>> address_fields['city'] = fields.String(attribute='city')
>>> address_fields['state'] = fields.String(attribute='state')
>>> address_fields['zip'] = fields.String(attribute='zip')
>>>
>>> resource_fields = {}
>>> resource_fields['name'] = fields.String
>>> resource_fields['billing_address'] = fields.Nested(address_fields)
>>> resource_fields['shipping_address'] = fields.Nested(address_fields)
>>> address1 = {'addr1': '123 fake street', 'city': 'New York', 'state': 'NY', 'zip': '10468'}
>>> address2 = {'addr1': '555 nowhere', 'city': 'New York', 'state': 'NY', 'zip': '10468'}
>>> data = { 'name': 'bob', 'billing_address': address1, 'shipping_address': address2}
>>>
>>> json.dumps(marshal_with(data, resource_fields))
'{"billing_address": {"line 1": "123 fake street", "line 2": null, "state": "NY", "zip": "10468", "city": "New York"}, "name": "bob", "shipping_address": {"line 1": "555 nowhere", "line 2": null, "state": "NY", "zip": "10468", "city": "New York"}}'

你可能感兴趣的:(Flask_RESTful)