标准化参数
- 对于一个类视图,可以指定好一些字段作标准化用于返回。
- 以后使用
ORM模型
或者自定义模型
的时候,类视图会自动的获取模型中的相应的字段,生成json
格式数据,然后再返回给客户端。 - 这需要导入
flask_restful.marshal_with
装饰器。 - 还需要写一个字典变量,来指定需要返回的标准化字段,以及该字段的数据类型。
- 在
get
方法中,返回自定义对象的时候,flask_restful
会自动的读取对象模型上的所有属性
。 - 组装成一个符合标准化参数的
json
格式字符串返回给客户端。
from flask import Flask
from flask_restful import Api,Resource,fields,marshal_with
app = Flask(__name__)
api = Api(app)
#flask_restful返回标准化参数
class News(object):
def __init__(self,title,content):
self.title =title
self.content =content
news = News('能力强的体现','能屈能伸')
class NewsView(Resource):
resource_fields ={ 'title': fields.String, 'content':fields.String }
@marshal_with(resource_fields)
def get(self):
return news api.add_resource(NewsView,'/news/')
if __name__ == '__main__':
app.run(debug=True)
重构返回参数
- 有的时候对外给出的属性名和模型内部的属性名不相同时,使用
attribute
可以配置这种映射。 - 比如: 想要返回模型对象
user.username
的值,但是在返回给外面的时候,想以uname
返回去。 - 在返回某些字段的时候,可以在指定
fields
的时候使用default
指定默认值
from flask import Flask,url_for,render_template
from flask_restful import Api,Resource,reqparse,inputs,fields,marshal_with
app = Flask(__name__)
api = Api(app)
class User():
def __init__(self,username,age):
self.username=username
self.age=age
self.signature=None
class UserView(Resource):
resource_fields={
#1.重命名属性
'uname':fields.String(attribute='username'),
'age':fields.Integer,
#2.默认值
'signature':fields.String(default='此人很懒,什么也没写') }
@marshal_with(resource_fields)
def get(self):
user = User('悟空',555)
return user
api.add_resource(UserView,'/user/')
if __name__ == '__main__':
app.run(debug=True)
复杂的参数结构
- 大型的互联网项目中,返回的数据格式,是比较复杂的结构。
- 复杂的结构无非就是
key
对应的value
又是一个json
,或者key
对应的是一个列表
,列表中的每项都是json
. - 那么可以使用一些特殊的字段来实现:
- 如在一个字段中放置一个列表,那么可以使用
fields.List
, - 如在一个字段下面又是一个字典,那么可以使用
fields.Nested
。 - 实体间关系有 1:1,1:n,n:n(转为2个1:n)
from flask import Flask,url_for,render_template
from flask_restful import Api,Resource,reqparse,inputs,fields,marshal_with
app = Flask(__name__)
api = Api(app)
#新闻系统后台 用户 新闻 新闻标签
class User():
def __init__(self,id,uname,age):
self.id = id
self.uname = uname
self.age = age
def __repr__(self):
return "<User:{id},{uname},{age}>"\
.format(id=self.id, uname=self.uname,age=self.age)
class News():
def __init__(self,id,title,content):
self.id=id
self.title=title
self.content=content
#关系映射
self.author=None
self.tags=[]
def __repr__(self):
return "<News:{id},{title},{content},{author},{tags}>"\
.format(id=self.id, title=self.title,content=self.content,\
author=self.author,tags=self.tags)
class NewsTag():
def __init__(self,id,name):
self.id=id
self.name=name
def __repr__(self):
return '<NewsTage:{id},{name}>'.format(id =self.id , name=self.name)
def createData():
user = User(110,'悟空',30)
tag1 = NewsTag(200,"要闻")
tag2 = NewsTag(210,"娱乐")
news =News(300,'吴京征服了世界上海拔最高的派出所','4月23日中午11点,吴京发了一条微博,配文“世界上海拔最高的派出所”,并@了另外一名演员张译。微博中有两张图片,第一张是吴京和张译两人坐在地上的合照,背后几个大字“中国边防”。第二张则是两人与派出所民警们的合照。 ')
news.author = user
#绑定新闻作者
news.tags.append(tag1)
#绑定新闻标签1
news.tags.append(tag2)
#绑定新闻标签2
print(news)
return news
class NewsView2(Resource):
resource_fields={
'id':fields.Integer,
'title': fields.String,
'content': fields.String,
#如在一个字段下面又是一个字典,可以使用fields.Nested({...})
'author': fields.Nested({
'id': fields.Integer,
'uname': fields.String,
'age':fields.Integer }),
#如要在一个字段中放置一个列表,那么可以使用fields.List(fields.Nested({...}))
'tags': fields.List(fields.Nested({
'id': fields.Integer,
'name': fields.String })) }
@marshal_with(resource_fields)
def get(self):
news = createData()
return news
api.add_resource(NewsView2,'/news2/')
if __name__ == '__main__':
app.run(debug=True)