class ProductProto(Protocol): """ Product """ field_model = StringField(validators=[validators.Length(max=200), validators.DataRequired()]) field_touch_bar = BooleanField() field_size = IntegerField(validators=[validators.AnyOf([13, 15])]) field_os = ProtocolField(OSProto) field_cpu = ProtocolField(CPUProto) field_ssd = IntegerField(validators=[validators.NumberRange(min=128, max=512)]) field_memory = IntegerField(validators=[validators.DataRequired()]) field_display = PlaceField(ProtocolField(DisplayProto), handler=json.loads) field_buy_date = DateTimeField(format="%Y-%m-%d %H:%M:%S") field_doc = LengthLimitTextField(limit=10) def post_data(self, data): """ Overwrite super class's method. This method will be called before the method 'data' returned. If you expect to convert the data structure or something else, you should do it in this method, because the parameter 'data' has been converted and validated successfully. """ # Add an unit of 'G'. data["ssd"] = str(data["ssd"]) + "G" # To convert from 'GB' to 'MB'. data["memory"] = data["memory"] * 1024 return data
class UserProto(Protocol): field_username = StringField(validators=[validators.DataRequired(), validators.Length(max=100)]) field_age = IntegerField(validators=[validators.DataRequired(), validators.NumberRange(max=28)]) # The 'discard=True' mean that the 'email' will not in the result data if 'nullable=True'. field_email = StringField(validators=[validators.DataRequired()], nullable=True, discard=True) field_phone = StringField(validators=[validators.DataRequired()], nullable=True, discard=False) # The 'sex' in result data will be used the default value if 'nullable=False'. field_sex = StringField(validators=[validators.AnyOf(["man", "woman"])], nullable=False, default="woman")
class DisplayProto(Protocol): """ Display """ field_type = StringField(validators=[validators.DataRequired()]) field_resolutions = UniqueFieldList( StringField(validators=[validators.Regular("[\d]+ by [\d]+")]), validators=[validators.Length(min=3)] ) field_ppi = IntegerField(validators=[validators.DataRequired()])
class OSProto(AppProto): """ OS """ field_apps = FieldList( ProtocolField(AppProto), validators=[validators.DataRequired()] ) def post_validate(self, fields): """ Overwrite super class's method. This method will be called before the method 'validate' returned. If you expect to have a custom validation with the fields, you should do it in this method. """ # Get the field object by the key. field_version = fields["version"] # Get the value of the field. field_version_value = field_version.value # To have a custom validation. if int(field_version_value.split(".")[1]) < 13: # Remember to set 'error'. field_version.error = "The version is too old" return False return True
class CPUProto(Protocol): """ CPU """ field_processor = StringField(validators=[validators.DataRequired()]) field_speed = FloatField(validators=[validators.AnyOf([2.3, 3.1])])
class AppProto(Protocol): """ App """ field_name = StringField(validators=[validators.Length(max=200), validators.DataRequired()]) field_version = StringField(validators=[validators.DataRequired()])