Flask ORM 学习笔记Part05:marshmallow的使用(中)
  qdp7fV9qUjiK 2023年12月06日 11 0

Nested 字段

Nested是字段fields中使用较多的。在 Marshmallow 中用于表示嵌套关系的字段。它允许在一个 Schema 中嵌套另一个 Schema,以处理复杂的对象关系。一般情况下可以与Model类中的relationship对应使用。

一对一

在model模块中Account与Profile是一对一关系,与之对应的AccountSchema和ProfileSchema使用如下定义嵌套关系字段

profile = fields.Nested('ProfileSchema', exclude=('account',))

一对多 多对多

在model模块中Account与Project是多对多关系,预支对应的AccountSchema 和 ProjectSchema 嵌套关系,并使用了many参数,另外为了防止在使用过程中出现循环嵌套引用,还是用exclued来排除一些字段。

class ProjectSchema(BaseSchema):
    project_name = fields.String(required=True)
    project_webhook = fields.String()

    hosts = fields.Nested('HostSchema', many=True, exclude=('project',))
    accounts = fields.Nested('AccountSchema', many=True, exclude=('projects',))


装饰器

Marshmallow中常用的装饰器有以下几个:

  1. pre_load: 在反序列化操作之前执行,用于预处理数据。可以在这个装饰器中添加自定义的预处理逻辑,例如对输入数据进行校验、过滤或转换等操作。
  2. post_load: 在反序列化操作之后执行,用于对反序列化后的对象进行进一步处理或验证。可以在这个装饰器中添加自定义的逻辑,例如根据特定的规则对数据进行修正或验证。
  3. pre_dump: 在序列化操作之前执行,用于准备要序列化的数据。可以在这个装饰器中添加自定义的准备逻辑,例如提取特定数据、计算生成序列化数据等。
  4. post_dump: 在序列化操作之后执行,用于对序列化后的数据进行进一步处理或验证。可以在这个装饰器中添加自定义的逻辑,例如对序列化后的数据进行校验、过滤或转换等操作。
  5. validates_schema: 用于验证序列化数据是否符合指定的 Schema(模式)。如果数据不符合模式,则抛出 ValidationError 异常。可以在这个装饰器中添加自定义的验证逻辑,例如根据特定的规则对数据进行验证。

这些装饰器可以用于在 Marshmallow 库的序列化和反序列化过程中添加额外的处理和验证逻辑,以满足特定的业务需求。


数据校验

Marshmallow在反序列化是,最重要的功能之一就是校验数据。

有多种方式进行数据校验:

使用validates_scheme装饰器,可以对整个data进行自定义的校验。

使用validates装饰器,可以指定要校验的field。

在field中使用validate属性。validate类说明,详见官网

下面代码中,

  • 使用了validates_schema装饰器,对gender进行校验,并修正大小写。
  • 使用validates装饰器校验height字段,并限定最小值。
  • age字段在filed字段中使用validate属性,指定数据范围。
class ProfileSchema(BaseSchema):
    fullname = fields.String()
    gender = fields.String()
    account = fields.Nested('AccountSchema', exclude=('profile',))
    age = fields.Int(validate=validate.Range(min=18, max=65))
    email = fields.Email()
    height = fields.Int()

    @validates_schema
    def validate_profile_gender(self, data, **kwargs):
        if data['gender'] not in ['M', 'F', 'f', 'm']:
            raise ValidationError(field_name='gender', message='gender must be M or F')
        else:
            data['gender'] = data['gender'].upper()
            return data

    @validates('height')
    def validate_age(self, data, **kwargs):
        if data <= 150:
            raise ValidationError('height must be taller than 150')
        else:
            return data

依据以上代码,如果是不合规数据,经过load操作,会抛出异常。

from app import app
from schema import *

with app.app_context():

    p_s = ProfileSchema()

    # age 不符合
    print("age 不符合")
    data = {"fullname": "川普", "gender": "M", "age": '71',"height": "185" }
    try:
        a = p_s.load(data)
        print(a)
    except Exception as E:
        print(str(E))

    # gender 不符合
    print("gender 不符合")
    data = {"fullname": "川普", "gender": "男", "age": '50',"height": "185" }
    try:
        a = p_s.load(data)
        print(a)
    except Exception as E:
        print(str(E))

    # height 不符合
    print("height 不符合")
    data = {"fullname": "川普", "gender": "M", "age": '50',"height": "145" }
    try:
        a = p_s.load(data)
        print(a)
    except Exception as E:
        print(str(E))

    # 符合,age 与 height 还被修改为Int
    print("符合,age 与 height 还被修改为Int")
    data = {"fullname": "川普", "gender": "M", "age": '50',"height": "185" }
    try:
        a = p_s.load(data)
        print(a)
    except Exception as E:
        print(str(E))

Flask ORM 学习笔记Part05:marshmallow的使用(中)_ORM

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月06日 0

暂无评论

qdp7fV9qUjiK