除非您需要反序列化为特定类或需要自定义序列化逻辑,否则您可以简单地执行此操作(改编自https://kimsereylam.com/python/2019/10/25/serialization-with-marshmallow.html):
from marshmallow import Schema, fields
from datetime import datetime
class UserSchema(Schema):
name = fields.Str(required=True)
email = fields.Email()
created_at = fields.DateTime()
schema = UserSchema()
data = { "name": "Some Guy", "email": "sguy@google.com": datetime.now() }
user = schema.load(data)
您还可以在您的类中创建一个函数,该函数创建一个带有验证规则的 dict,尽管它仍然是多余的,但它允许您将所有内容保留在模型类中:
class User:
def __init__(name, email, created_at):
self.name = name
self.email = email
self.created_at = created_at
@classmethod
def Schema(cls):
return {"name": fields.Str(), "email": fields.Email(), "created_at": fields.DateTime()}
UserSchema = Schema.from_dict(User.Schema)
如果您需要强类型和完整的验证功能,请考虑 flask-pydantic 或 marshmallow-dataclass。
marshmallow-dataclass 提供了许多与 marshmallow 类似的验证功能。不过它有点束缚你的手。它没有对自定义字段/多态性的内置支持(必须改用 marshmallow-union),并且似乎不能很好地与 flask-marshmallow 和 marshmallow-sqlalchemy 等堆栈包一起使用。 https://pypi.org/project/marshmallow-dataclass/
from typing import ClassVar, Type
from marshmallow_dataclass import dataclasses
from marshmallow import Schema, field, validate
@dataclass
class Person:
name: str = field(metadata=dict(load_only=True))
height: float = field(metadata=dict(validate=validate.Range(min=0)))
Schema: ClassVar[Type[Schema]] = Schema
Person.Schema().dump(Person('Bob', 2.0))
# => {'height': 2.0}
从验证的角度来看,flask-pydantic 不太优雅,但提供了许多相同的功能,并且验证内置在类中。请注意,像 min/max 这样的简单验证比 marshmallow 更尴尬。就个人而言,我更喜欢将视图/api 逻辑排除在课堂之外。https://pypi.org/project/Flask-Pydantic/
from typing import Optional
from flask import Flask, request
from pydantic import BaseModel
from flask_pydantic import validate
app = Flask("flask_pydantic_app")
class QueryModel(BaseModel):
age: int
class ResponseModel(BaseModel):
id: int
age: int
name: str
nickname: Optional[str]
# Example 1: query parameters only
@app.route("/", methods=["GET"])
@validate()
def get(query:QueryModel):
age = query.age
return ResponseModel(
age=age,
id=0, name="abc", nickname="123"
)