marshmallow之schema嵌套

schema嵌套

schema能夠嵌套使用以表示對象間的關係(如外鍵關係)。python

例以下例中Blog有一個用User對象表示的author屬性:app

import datetime as dt

class User(object):
    def __init__(self, name, email):
        self.name = name
        self.email = email
        self.created_at = dt.datetime.now()
        self.friends = []
        self.employer = None

class Blog(object):
    def __init__(self, title, author):
        self.title = title
        self.author = author  # A User object

使用Nested子類接收嵌套的schema表示兩者的關係:code

from marshmallow import Schema, fields, pprint

class UserSchema(Schema):
    name = fields.String()
    email = fields.Email()
    created_at = fields.DateTime()

class BlogSchema(Schema):
    title = fields.String()
    author = fields.Nested(UserSchema)

序列化後的blog對象將包含嵌套的user對象:對象

user = User(name="Monty", email="monty@python.org")
blog = Blog(title="Something Completely Different", author=user)
result = BlogSchema().dump(blog)
pprint(result)
# {'title': u'Something Completely Different',
#  'author': {'name': u'Monty',
#             'email': u'monty@python.org',
#             'created_at': '2014-08-17T14:58:57.600623+00:00'}}

若是field嵌套對象是一個集合,必須設置many=True,如collaborators = fields.Nested(UserSchema, many=True)blog

指定嵌套對象的序列化字段

設置only參數顯式地指定對嵌套對象的哪些屬性進行序列化:遞歸

class BlogSchema2(Schema):
    title = fields.String()
    author = fields.Nested(UserSchema, only=["email"])

schema = BlogSchema2()
result = schema.dump(blog)
pprint(result)
# {
#     'title': u'Something Completely Different',
#     'author': {'email': u'monty@python.org'}
# }

使用點分隔符能夠表示深層嵌套對象的屬性:字符串

class SiteSchema(Schema):
    blog = fields.Nested(BlogSchema2)

schema = SiteSchema(only=['blog.author.email'])
result, errors = schema.dump(site)
pprint(result)
# {
#     'blog': {
#         'author': {'email': u'monty@python.org'}
#     }
# }

若是給only參數傳遞的是字符串(上面的例子傳遞的是列表),將返回單個值(上面的例子返回的是鍵值映射)或值的列表(須要設置many=True):it

class UserSchema(Schema):
    name = fields.String()
    email = fields.Email()
    friends = fields.Nested('self', only='name', many=True)
# ... create ``user`` ...
result, errors = UserSchema().dump(user)
pprint(result)
# {
#     "name": "Steve",
#     "email": "steve@example.com",
#     "friends": ["Mike", "Joe"]
# }

雙向嵌套

對於兩個互相嵌套的對象,能夠使用類名引用嵌套的schema,即使是引用時該schema尚未被定義。io

在下面的例子中,Author和Book對象是一對多的關係:class

class AuthorSchema(Schema):
    # 必須使用only或exclude參數避免無限遞歸
    books = fields.Nested('BookSchema', many=True, exclude=('author', ))
    class Meta:
        fields = ('id', 'name', 'books')

class BookSchema(Schema):
    author = fields.Nested(AuthorSchema, only=('id', 'name'))
    class Meta:
        fields = ('id', 'title', 'author')
from marshmallow import pprint
from mymodels import Author, Book

author = Author(name='William Faulkner')
book = Book(title='As I Lay Dying', author=author)
book_result, errors = BookSchema().dump(book)
pprint(book_result, indent=2)
# {
#   "id": 124,
#   "title": "As I Lay Dying",
#   "author": {
#     "id": 8,
#     "name": "William Faulkner"
#   }
# }

author_result, errors = AuthorSchema().dump(author)
pprint(author_result, indent=2)
# {
#   "id": 8,
#   "name": "William Faulkner",
#   "books": [
#     {
#       "id": 124,
#       "title": "As I Lay Dying"
#     }
#   ]
# }

也能夠使用導入模塊的方式傳遞嵌套schema,如books = fields.Nested('path.to.BookSchema', many=True, exclude=('author', ))

schema自嵌套

給Nested傳遞字符串參數self表示和對象自己的關係:

class UserSchema(Schema):
    name = fields.String()
    email = fields.Email()
    friends = fields.Nested('self', many=True)
    # Use the 'exclude' argument to avoid infinite recursion
    employer = fields.Nested('self', exclude=('employer', ), default=None)

user = User("Steve", 'steve@example.com')
user.friends.append(User("Mike", 'mike@example.com'))
user.friends.append(User('Joe', 'joe@example.com'))
user.employer = User('Dirk', 'dirk@example.com')
result = UserSchema().dump(user)
pprint(result.data, indent=2)
# {
#     "name": "Steve",
#     "email": "steve@example.com",
#     "friends": [
#         {
#             "name": "Mike",
#             "email": "mike@example.com",
#             "friends": [],
#             "employer": null
#         },
#         {
#             "name": "Joe",
#             "email": "joe@example.com",
#             "friends": [],
#             "employer": null
#         }
#     ],
#     "employer": {
#         "name": "Dirk",
#         "email": "dirk@example.com",
#         "friends": []
#     }
# }
相關文章
相關標籤/搜索