The allow_blank was added to address #76 . It is used to determine whether to allow the empty string as a valid value.
This parameter is technically redundant, since the same validation can be achieved using validate.Length.
from marshamallow import fields, validate
not_blank = validate.Length(min=1, error='Field cannot be blank')
f = fields.Str(validate=not_blank)
f.deserialize('') # => Error: Field may not be blank.
I propose to remove the allow_blank parameter, as it is unnecessary API.
There is a valid use case for an option to disallow empty strings:
When you want to show a special error message for missing values including empty strings:
name = fields.String(
required="Please enter your user name.",
validate=[
validate.Length(min=4, max=20,
error="User name must have between {min} and {max} characters."),
validate.Regexp(r"[a-zA-Z0-9_\-]*$",
error="User name must not contain special characters"
"(except _ und -)")
)
In that case, adding a Length(min=1) validator like this is problematic:
name = fields.String(
required="Please enter your user name.",
validate=[
validate.Length(min=1, error="Please enter your user name."),
validate.Length(min=4, max=20,
error="User name must have between {min} and {max} characters."),
validate.Regexp(r"[a-zA-Z0-9_\-]*$",
error="User name must not contain special characters"
"(except _ and -)")
)
because an empty string would trigger two error messages (from both length validators):
# you would get 2 'name'-errors:
# 'name': ['Please enter your user name.', 'User name must have between 4 and 20 characters.']
I've just had a similar problem with an Integer-field. How would you solve the task to show two different messages for these two cases:
"12abc&$". You would like to show an error-message along the lines of "Only number-values are allowed."Currently I don't see a nice way to distinguish missing input from invalid numerical input, because marshmallow treats the empty string as non-missing. This is not a problem for JSON-submitted data (e.g. from Angular, ...) of course. But for standard browser forms that are POSTed, this will be relevant.
@martinstein Facing the same problem you are. Changing from colander to marshmallow and these empty string values that come default from form fields are breaking all of our backend integer validation. Did you ever come up with a solution? Right now all of our options are pretty ugly.
@martinstein @drivelous You can always preprocess data e.g. remove empty string values:
def load_data(data):
return MyDataSchema(strict=True).load({
k: v for k, v in data.iteritems() if v != ''
}).data
I would say that integers should always be integers not string representation, but that does not work in case of web forms. If you still need to check that value contains only digits, you can add simple regex validator:
marshmallow.validate.Regexp('^(\+|-)?[0-9]+$', error='Should be integer')
@maximkulkin ahh thank you for the solution. It won't work in our case because empty strings are valid values for many fields. A lot of breakage occurs because extra checks need to be added downstream (e.g. it's necessary to tell validators whether a field is required because they're trying to validate an empty string, something which would've been caught and filtered if an allow_blank flag existed).
I agree that integers should always be integers but given the nature of web forms and the fact that other libraries support coercing empty strings to None, it would've been real nice to have that option for backwards compatibility.
Most helpful comment
There is a valid use case for an option to disallow empty strings:
When you want to show a special error message for missing values including empty strings:
In that case, adding a Length(min=1) validator like this is problematic:
because an empty string would trigger two error messages (from both length validators):