marshmallow关系处理

Posted dowi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 # }

 

以上是关于marshmallow关系处理的主要内容,如果未能解决你的问题,请参考以下文章

onRequestPermissionsResult 在片段中不起作用

[Python]Marshmallow 代码

将应用程序更新为 Marshmallow 或 Nougat

检查哪些代码使用权限

仅要求 Android Marshmallow 的运行时权限?

Android Marshmallow:在运行时更改权限会使应用程序崩溃