I have a parent marshmallow schema "ParentSchema" and 2 nested children schemas "ChildSchema1" and "ChildSchema2". Both nested children schemas are taking advantage of the @validates_schema decorator for field validation from marshmallow. They look like this:
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')
Given that both ChildSchema1 and ChildSchema2 have a field of the same name, with the same validator function, I'd love to follow DRY Principle and pull that function out to ParentSchema.py.
A solution I found is creating a separate class to host the shared validation functions:
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')
And consume that from ChildSchema1 and ChildSchema2 by removing the @validates decorator and using the validate
parameter in the schema field like this.
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, validates
def validate_common_field(self, common_field):
try:
# Validation logic
except:
raise ValidationError('common_field is not valid')
Your approach with a separate function is fine.
If the common field is shared by both children, you could also use inheritance to reflect that and factorize the field and the logic.
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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.