【问题标题】:Marshmallow Parent Schema - How to share a validation decorator between child schemas?Marshmallow Parent Schema - 如何在子模式之间共享验证装饰器?
【发布时间】:2019-07-01 00:54:56
【问题描述】:

我有一个父棉花糖架构“ParentSchema”和 2 个嵌套的子架构“ChildSchema1”和“ChildSchema2”。两个嵌套的子模式都利用 @validates_schema 装饰器从棉花糖进行字段验证。它们看起来像这样:

ParenSchema.py

from marshmallow import Schema, fields
from schemas.childSchema1 import ChildSchema1
from schemas.childSchema2 import ChildSchema2

    class ParentSchema(Schema):
        child1 = fields.Nested(ChildSchema1)
        child2 = fields.Nested(ChildSchema2)
        foo = fields.String()
        bar = fields.String()

ChildSchema1.py

from marshmallow import Schema, pprint, post_load
from marshmallow import fields, ValidationError, validates, validates_schema

class ChildSchema1(Schema):
    field1 = fields.String()
    field2 = fields.String()
    common_field = fields.String()

    @validates("common_field")
    def validate_common_field(self, common_field):
        try:
            # Validation logic
        except:
            raise ValidationError('common_field is not valid')

ChildSchema2.py

from marshmallow import Schema, pprint, post_load
from marshmallow import fields, ValidationError, validates, validates_schema

class ChildSchema2(Schema):
    common_field = fields.String()
    field3 = fields.String()

    @validates("common_field")
    def validate_common_field(self, common_field):
        try:
            # Exact Same Validation logic as common_field from ChildSchema1
        except:
            raise ValidationError('common_field is not valid')

鉴于 ChildSchema1 和 ChildSchema2 都有一个同名字段,具有相同的验证器函数,我很想关注 DRY Principle 并将该函数拉到 ParentSchema.py。

【问题讨论】:

    标签: python python-3.x marshmallow


    【解决方案1】:

    我发现的一个解决方案是创建一个单独的类来托管共享验证函数:

    def validate_common_field(self, common_field):
        try:
            # Exact Same Validation logic as common_field from ChildSchema1
        except:
            raise ValidationError('common_field is not valid')
    

    然后通过删除 @validates 装饰器并在架构字段中使用 validate 参数来使用来自 ChildSchema1 和 ChildSchema2 的内容,如下所示。

    ChildSchema1.py

    from marshmallow import Schema, pprint, post_load
    from marshmallow import fields, ValidationError, validates, validates_schema
    from validators import *
    
    class ChildSchema1(Schema):
        field1 = fields.String()
        field2 = fields.String()
        common_field = fields.String(validate=validate_common_field)
    

    validators.py from marshmallow import ValidationError, 验证

    def validate_common_field(self, common_field):
            try:
                # Validation logic
            except:
                raise ValidationError('common_field is not valid')
    

    【讨论】:

      【解决方案2】:

      您使用单独函数的方法很好。

      如果公共字段由两个孩子共享,您还可以使用继承来反映它并分解字段和逻辑。

      class ChildSchema(Schema):
          common_field = fields.String()
      
          @validates("common_field")
          def validate_common_field(self, common_field):
              try:
                  # Validation logic
              except:
                  raise ValidationError('common_field is not valid')
      
      class ChildSchema1(ChildSchema):
          field1 = fields.String()
          field2 = fields.String()
      
      class ChildSchema2(ChildSchema):
          field3 = fields.String()
      

      【讨论】:

        猜你喜欢
        • 2020-04-07
        • 1970-01-01
        • 1970-01-01
        • 2015-10-01
        • 1970-01-01
        • 2014-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多