官术网_书友最值得收藏!

Serializing results

We need to return our results. The easiest way to do so is by defining the shape the JSON result should have through a serializer or marshalling model (https://flask-restplus.readthedocs.io/en/stable/marshalling.html).

A serializer model is defined as a dictionary with the expected fields and a field type:

from flask_restplus import fields

model = {
'id': fields.Integer(),
'username': fields.String(),
'text': fields.String(),
'timestamp': fields.DateTime(),
}
thought_model = api_namespace.model('Thought', model)

The model will take a Python object, and convert each of the attributes into the corresponding JSON element, as defined in the field:

@api_namespace.route('/me/thoughts/')
class MeThoughtListCreate(Resource):

@api_namespace.marshal_with(thought_model)
def post(self):
...
new_thought = ThoughtModel(...)
return new_thought

Note that new_thought is a ThoughtModel object, as retrieved by SQLAlchemy. We'll see it in detail next, but for now, it suffices to say that it has all the attributes defined in the model: id, username, text, and timestamp.

Any attribute not present in the memory object will have a value of None by default. You can change this default to a value that will be returned. You can specify a function, so it will be called to retrieve a value when the response is generated. This is a way of adding dynamic information to your object:

model = {
    'timestamp': fields.DateTime(default=datetime.utcnow),
}

You can also add the name of the attribute to be serialized, in case it's different than the expected outcome, or add a lambda function that will be called to retrieve the value:

model = {
    'thought_text': fields.String(attribute='text'),
'thought_username': fields.String(attribute=lambda x: x.username),
}

For more complex objects, you can nest values like this. Note this defines two models from the point of view of the documentation and that each Nested element creates a new scope. You can also use List to add multiple instances of the same kind:

extra = {
'info': fields.String(),
}
extra_info = api_namespace.model('ExtraInfo', extra)

model
= { 'extra': fields.Nested(extra),
'extra_list': fields.List(fields.Nested(extra)),
}

Some of the available fields have more options, such as the date format for the DateTime fields. Check the full field's documentation (https://flask-restplus.readthedocs.io/en/stable/api.html#models) for more details. 

If you return a list of elements, add the as_list=True parameter in the marshal_with decorator:

@api_namespace.route('/me/thoughts/')
class MeThoughtListCreate(Resource):

@api_namespace.marshal_with(thought_model, as_list=True)
def get(self):
...
thoughts = (
ThoughtModel.query.filter(
ThoughtModel.username == username
)
.order_by('id').all()
)
return thoughts

The marshal_with decorator will transform the result object from a Python object into the corresponding JSON data object. 

By default, it will return a http.client.OK (200) status code, but we can return a different status code returning two values: the first is the object to marshal and the second is the status code. The code parameter in the marshal_with decorator is used for documentation purposes. Note, in this case, we need to add the specific marshal call:

@api_namespace.route('/me/thoughts/')
class MeThoughtListCreate(Resource):

@api_namespace.marshal_with(thought_model,
code=http.client.CREATED)

def post(self):
...
result = api_namespace.marshal(new_thought, thought_model)
return result, http.client.CREATED

The Swagger documentation will display all your used-defined marshal objects:

The end of the Swagger page
One inconvenience of Flask-RESTPlus is that to input and output the same objects, they need to be defined twice, as the modules for input and output are different. This is not the case in some other RESTful frameworks, for example, in the Django REST framework ( https://www.django-rest-framework.org/). The maintainers of Flask-RESTPlus are aware of this, and, according to them, they'll be integrating an external module, probably marshmallow ( https://marshmallow.readthedocs.io/en/stable/). You can integrate it manually if you like, as Flask is flexible enough to do so, take a look at this example ( https://marshmallow.readthedocs.io/en/stable/examples.html#quotes-api-flask-sqlalchemy).

For more details, you can check the full marshalling documentation at https://flask-restplus.readthedocs.io/en/stable/marshalling.html) of Flask-RESTPlus.

主站蜘蛛池模板: 通化县| 巴南区| 静乐县| 三明市| 绍兴市| 孝感市| 修文县| 大邑县| 襄城县| 通河县| 镇江市| 疏勒县| 金溪县| 原平市| 延庆县| 汝南县| 黔南| 西宁市| 胶州市| 通渭县| 兴化市| 仙游县| 锦屏县| 崇左市| 正安县| 会同县| 清涧县| 武强县| 玛曲县| 屏山县| 扬州市| 时尚| 阜康市| 江油市| 枣阳市| 禹城市| 土默特左旗| 嘉兴市| 阿拉善右旗| 屯昌县| 华容县|