标准化参数

  • 对于一个类视图,可以指定好一些字段作标准化用于返回。
  • 以后使用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)