zoukankan      html  css  js  c++  java
  • marshmallow关系处理

    • Nesting Schemas

    当模型间拥有关系,比如外键,schema如何处理呢?例如:blog和user之间的关系

     1 class User(object):
     2     def __init__(self, name, email):
     3         self.name = name
     4         self.email = email
     5         self.created_at = dt.datetime.now()
     6         self.friends = []
     7         self.employer = None
     8 
     9 class Blog(object):
    10     def __init__(self, title, author):
    11         self.title = title
    12         self.author = author

    使用Nested字段来代表关系,并传入相应的schema类

     1 from marshmallow import Schema, fields
     2 
     3 class UserSchema(Schema):
     4     name = fields.String()
     5     email = fields.Email()
     6     created_at = fields.DateTime()
     7 
     8 class BlogSchema(Schema):
     9     title = fields.String()
    10     author = fields.Nested(UserSchema)

    序列化blog对象则会嵌入user描述

     1 from marshmallow import Schema, fields, pprint
     2 
     3 user = User2(name="Monty", email="monty@python.org")
     4 blog = Blog(title="Something Completely Different", author=user)
     5 pprint(BlogSchema().dump(blog))
     6 
     7 {'author': {'created_at': '2019-11-14T15:28:09.212278',
     8             'email': 'monty@python.org',
     9             'name': 'Monty'},
    10  'title': 'Something Completely Different'}

    注意:如果field是多个嵌入对象的集合,则必须设置many=True

    collaborators = fields.Nested(UserSchema, many=True)
    • Specifying Which Fields to Nest

    如果想指定序列化时嵌入对象的某几个字段,可以设置only参数

     1 class BlogSchema(Schema):
     2     title = fields.String()
     3     author = fields.Nested(UserSchema, only=["email"])
     4 
     5 user = User(name="Monty", email="monty@python.org")
     6 blog = Blog(title="Something Completely Different", author=user)
     7 pprint(BlogSchema().dump(blog))
     8 
     9 {'author': {'email': 'monty@python.org'},
    10  'title': 'Something Completely Different'}

    如果有更深度的嵌套,可以使用“.”符号连接

     1 class Site(object):
     2     def __init__(self, blog):
     3         self.blog = blog
     4 
     5 class SiteSchema(Schema):
     6     blog = fields.Nested(BlogSchema)
     7 
     8 user = User(name="Mike", email="mike@python.org")
     9 blog = Blog(title="something is wrong", author=user)
    10 site = Site(blog=blog)
    11 schema = SiteSchema(only=['blog.author.email'])
    12 pprint(schema.dump(site))
    13 
    14 {'blog': {'author': {'email': 'mike@python.org'}}}

    使用Pluck字段可以用单个值来替换嵌套的数据

     1 class UserSchema(Schema):
     2     name = fields.String()
     3     email = fields.Email()
     4     friends = fields.Pluck("self", "name", many=True)
     5 
     6 user1 = User(name="Mike", email="mike@example.com")
     7 user2 = User(name="Tom", email="tom@example.com")
     8 user3 = User(name="Steve", email="steve@example.com")
     9 user3.friends = [user1, user2]
    10 pprint(UserSchema().dump(user3))
    11 
    12 {'email': 'steve@example.com', 'friends': ['Mike', 'Tom'], 'name': 'Steve'}
    13 
    14 data = {
    15         "name": "Steve",
    16         "email": "steve@example.com",
    17         "friends": [
    18             "Tom",
    19             "Mike"
    20         ]
    21 }
    22 pprint(UserSchema().load(data))
    23 
    24 {'email': 'steve@example.com',
    25  'friends': [{'name': 'Tom'}, {'name': 'Mike'}],
    26  'name': 'Steve'}

    也可以使用exclude参数来排除不要的字段,对于深度嵌套,同样可以使用“.”符号连接

    • Partial Loading

    反序列化时,嵌套的schemas也可以继承父类的partial参数

     1 class UserSchemaStrict(Schema):
     2     name = fields.String(required=True)
     3     email = fields.Email()
     4     created_at = fields.DateTime(required=True)
     5 
     6 class BlogSchemaStrict(Schema):
     7     title = fields.String(required=True)
     8     author = fields.Nested(UserSchemaStrict, required=True)
     9 
    10 schema = BlogSchemaStrict()
    11 blog = {"title": "Something Completely Different", "author": {}}
    12 result = schema.load(blog, partial=True)
    13 pprint(result)
    14 
    15 {'author': {}, 'title': 'Something Completely Different'}

    同样可以通过“.”符号连接来指定partial字段的子集

    1 author = {"name": "Monty", "email": "monty@example.com"}
    2 blog = {"title": "Something Completely Different", "author": author}
    3 result = schema.load(blog, partial=("title", "author.created_at"))
    4 pprint(result)
    5 
    6 {'author': {'email': 'monty@example.com', 'name': 'Monty'},
    7  'title': 'Something Completely Different'}
    • Two-way Nesting

    如果两个对象相互嵌套,则Nested可以传入类名的字符串形式,这允许在未定义该类时定义一个嵌套的schema类

     1 class Author(object):
     2     def __init__(self, name, email):
     3         self.name = name
     4         self.email = email
     5         self.books = []
     6 
     7 class Book(object):
     8     def __init__(self, title, author):
     9         self.title = title
    10         self.author = author
    11 
    12 class AuthorSchema(Schema):
    13     name = fields.Str()
    14     email = fields.Email()
    15     # Make sure to use the 'only' or 'exclude' params
    16     # to avoid infinite recursion
    17     books = fields.Nested('BookSchema', many=True, exclude=('author',))
    18 
    19     class Meta:
    20         fields = ('name', 'email', 'books')
    21 
    22 class BookSchema(Schema):
    23     title = fields.Str()
    24     author = fields.Nested(AuthorSchema, only=('name', 'email'))
    25 
    26     class Meta:
    27         fields = ('title', 'author')
    28 
    29 author = Author(name="Mike", email="mike@yooh.com")
    30 book = Book(title="This is a joke", author=author)
    31 pprint(BookSchema().dump(book))
    32 
    33 {'author': {'email': 'mike@yooh.com', 'name': 'Mike'},
    34  'title': 'This is a joke'}
    35 
    36 author.books = [book]
    37 pprint(AuthorSchema().dump(author))
    38 
    39 {'books': [{'title': 'This is a joke'}],
    40  'email': 'mike@yooh.com',
    41  'name': 'Mike'}
    42 
    • Nesting A Schema Within Itself

    如果需要自引用,则Nested传入‘self’即可

     1 class UserSchema(Schema):
     2     name = fields.String()
     3     email = fields.Email()
     4     friends = fields.Nested("self", many=True)
     5     # Use the 'exclude' argument to avoid infinite recursion
     6     employer = fields.Nested("self", exclude=("employer",), default=None)
     7 
     8 user = User("Steve", "steve@example.com")
     9 user.friends.append(User("Mike", "mike@example.com"))
    10 user.friends.append(User("Joe", "joe@example.com"))
    11 user.employer = User("Dirk", "dirk@example.com")
    12 result = UserSchema().dump(user)
    13 pprint(result, indent=2)
    14 
    15 # {
    16 #     "name": "Steve",
    17 #     "email": "steve@example.com",
    18 #     "friends": [
    19 #         {
    20 #             "name": "Mike",
    21 #             "email": "mike@example.com",
    22 #             "friends": [],
    23 #             "employer": null
    24 #         },
    25 #         {
    26 #             "name": "Joe",
    27 #             "email": "joe@example.com",
    28 #             "friends": [],
    29 #             "employer": null
    30 #         }
    31 #     ],
    32 #     "employer": {
    33 #         "name": "Dirk",
    34 #         "email": "dirk@example.com",
    35 #         "friends": []
    36 #     }
    37 # }
  • 相关阅读:
    try catch finally中return的执行顺序
    多线程和同步
    orecle常用函数
    java如何调用接口 2
    orecle 函数
    ==和equals在比较字符串时候的区别
    orecle触发器
    java实现同步的方法
    java如何调用接口
    SMM+maven下的log4j配置打印sql
  • 原文地址:https://www.cnblogs.com/dowi/p/11858858.html
Copyright © 2011-2022 走看看