Flask Marshmallow JSON 个字段
Flask Marshmallow JSON fields
我已经定义了一个需要数据的 POST 调用:
{
"one" : "hello",
"two" : "world",
"three" : {
"ab": "123",
"cd": false
}
}
为此,我可以定义one
和two
,但不确定定义three
的正确性。如何在 Marshmallow 中指定 JSON 字段?我能够定义基本字段,例如:
from marshmallow import Schema, post_load, fields
class Foo(object):
def __init__(self, one, two=None):
self.one = one
self.two = two
class MySchema(Schema):
one = fields.String(required=True)
two = fields.String()
@post_load
def create_foo(self, data, **kwargs):
return Foo(**data)
如何在 MySchema
中定义 three
?我应该:
- 简单地将它作为一个字符串并进行操作以使用
json.loads()/json.dumps()
将其加载为json?或者有没有办法正确定义它?
- 定义为
fields.Dict
?
- 我可以为这个字段定义一个单独的
Schema
吗
- 我应该延长
field.Field
吗?
我正在查看 https://marshmallow.readthedocs.io/en/3.0/api_reference.html,但仍不确定。 JSON 子字段或嵌套的 JSON 似乎是一个常见的用例,但我找不到与此相关的任何内容。
这可以通过嵌套架构来完成:https://marshmallow.readthedocs.io/en/3.0/nesting.html
您的架构类似于:
class MySchema(Schema):
one = fields.String(required=True)
two = fields.String()
three = fields.Nested(ThreeSchema)
class ThreeSchema(Schema):
ab = fields.String()
cd = fields.Boolean()
您可以创建自己的字段
import json
from marshmallow import fields
class JSON(fields.Field):
def _deserialize(self, value, attr, data, **kwargs):
if value:
try:
return json.loads(value)
except ValueError:
return None
return None
...
from marshmallow import fields, Schema
from schemas.base import JSON
class ObjectSchema(Schema):
id = fields.Integer()
data = JSON()
如果您想在字段中支持任意 嵌套值,而不是为它们定义架构,您可以使用:
fields.Dict()
(接受任意 Python dict
,或者等效地,任意 JSON 对象),或
fields.Raw()
(对于任意 Python 对象,或者等效地,任意 JSON 值)
您可以 运行 一个示例脚本,它基于问题中的示例使用了以上两个:
import json
from marshmallow import Schema, fields, post_load
class Foo(object):
def __init__(self, one, two=None, three=None, four=None):
self.one = one
self.two = two
self.three = three
self.four = four
class MySchema(Schema):
one = fields.String(required=True)
two = fields.String()
three = fields.Dict()
four = fields.Raw()
@post_load
def create_foo(self, data, **kwargs):
return Foo(**data)
post_data = json.loads(
"""{
"one" : "hello",
"two" : "world",
"three" : {
"ab": "123",
"cd": false
},
"four" : 567
}"""
)
foo = MySchema().load(post_data)
print(foo.one)
print(foo.two)
print(foo.three)
print(foo.four)
我已经定义了一个需要数据的 POST 调用:
{
"one" : "hello",
"two" : "world",
"three" : {
"ab": "123",
"cd": false
}
}
为此,我可以定义one
和two
,但不确定定义three
的正确性。如何在 Marshmallow 中指定 JSON 字段?我能够定义基本字段,例如:
from marshmallow import Schema, post_load, fields
class Foo(object):
def __init__(self, one, two=None):
self.one = one
self.two = two
class MySchema(Schema):
one = fields.String(required=True)
two = fields.String()
@post_load
def create_foo(self, data, **kwargs):
return Foo(**data)
如何在 MySchema
中定义 three
?我应该:
- 简单地将它作为一个字符串并进行操作以使用
json.loads()/json.dumps()
将其加载为json?或者有没有办法正确定义它? - 定义为
fields.Dict
? - 我可以为这个字段定义一个单独的
Schema
吗 - 我应该延长
field.Field
吗?
我正在查看 https://marshmallow.readthedocs.io/en/3.0/api_reference.html,但仍不确定。 JSON 子字段或嵌套的 JSON 似乎是一个常见的用例,但我找不到与此相关的任何内容。
这可以通过嵌套架构来完成:https://marshmallow.readthedocs.io/en/3.0/nesting.html
您的架构类似于:
class MySchema(Schema):
one = fields.String(required=True)
two = fields.String()
three = fields.Nested(ThreeSchema)
class ThreeSchema(Schema):
ab = fields.String()
cd = fields.Boolean()
您可以创建自己的字段
import json
from marshmallow import fields
class JSON(fields.Field):
def _deserialize(self, value, attr, data, **kwargs):
if value:
try:
return json.loads(value)
except ValueError:
return None
return None
...
from marshmallow import fields, Schema
from schemas.base import JSON
class ObjectSchema(Schema):
id = fields.Integer()
data = JSON()
如果您想在字段中支持任意 嵌套值,而不是为它们定义架构,您可以使用:
fields.Dict()
(接受任意 Pythondict
,或者等效地,任意 JSON 对象),或fields.Raw()
(对于任意 Python 对象,或者等效地,任意 JSON 值)
您可以 运行 一个示例脚本,它基于问题中的示例使用了以上两个:
import json
from marshmallow import Schema, fields, post_load
class Foo(object):
def __init__(self, one, two=None, three=None, four=None):
self.one = one
self.two = two
self.three = three
self.four = four
class MySchema(Schema):
one = fields.String(required=True)
two = fields.String()
three = fields.Dict()
four = fields.Raw()
@post_load
def create_foo(self, data, **kwargs):
return Foo(**data)
post_data = json.loads(
"""{
"one" : "hello",
"two" : "world",
"three" : {
"ab": "123",
"cd": false
},
"four" : 567
}"""
)
foo = MySchema().load(post_data)
print(foo.one)
print(foo.two)
print(foo.three)
print(foo.four)