Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rules: different, uuid, distinct, required_if, required_with #44

Merged
merged 12 commits into from
Nov 26, 2020
127 changes: 124 additions & 3 deletions src/masonite/validation/Validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,18 @@ class required(BaseValidation):
def passes(self, attribute, key, dictionary):
"""The passing criteria for this rule.

This should return a True boolean value.
The key must exist in the dictionary and return a True boolean value.
The key can use * notation.

Arguments:
attribute {mixed} -- The value found within the dictionary
key {string} -- The key in the dictionary being searched for.
This key may or may not exist in the dictionary.
dictionary {dict} -- The dictionary being searched

Returns:
bool
"""
return attribute or key in dictionary
return self.find(key, dictionary) and attribute

def message(self, key):
"""A message to show when this rule fails
Expand Down Expand Up @@ -1029,6 +1029,122 @@ def negated_message(self, attribute):
return "The {} is a valid {} postal code.".format(attribute, self.locale)


class different(BaseValidation):
"""The field under validation must be different than an other given field."""
def __init__(self, validations, other_field, messages={}, raises={}):
super().__init__(validations, messages=messages, raises=raises)
self.other_field = other_field

def passes(self, attribute, key, dictionary):
other_value = dictionary.get(self.other_field, None)
return attribute != other_value

def message(self, attribute):
return "The {} value must be different than {} value.".format(attribute, self.other_field)

def negated_message(self, attribute):
return "The {} value be the same as {} value.".format(attribute, self.other_field)


class uuid(BaseValidation):
"""The field under validation must be a valid UUID. The UUID version standard
can be precised (1,3,4,5)."""
def __init__(self, validations, version=4, messages={}, raises={}):
super().__init__(validations, messages=messages, raises=raises)
self.version = version
self.uuid_type = "UUID"
if version:
self.uuid_type = "UUID {0}".format(self.version)

def passes(self, attribute, key, dictionary):
from uuid import UUID
try:
uuid_value = UUID(str(attribute))
return uuid_value.version == int(self.version)
except ValueError:
return False

def message(self, attribute):
return "The {} value must be a valid {}.".format(attribute, self.uuid_type)

def negated_message(self, attribute):
return "The {} value must not be a valid {}.".format(attribute, self.uuid_type)


class required_if(BaseValidation):
"""The field under validation must be present and not empty only
if an other field has a given value."""
def __init__(self, validations, other_field, value, messages={}, raises={}):
super().__init__(validations, messages=messages, raises=raises)
self.other_field = other_field
self.value = value

def passes(self, attribute, key, dictionary):
if dictionary.get(self.other_field, None) == self.value:
return required.passes(self, attribute, key, dictionary)

return True

def message(self, attribute):
return "The {} is required because {}={}.".format(attribute, self.other_field, self.value)

def negated_message(self, attribute):
return "The {} is not required because {}={} or {} is not present.".format(
attribute, self.other_field, self.value, self.other_field
)


class required_with(BaseValidation):
"""The field under validation must be present and not empty only
if any of the other specified fields are present."""

def __init__(self, validations, other_fields, messages={}, raises={}):
super().__init__(validations, messages=messages, raises=raises)
if not isinstance(other_fields, list):
if "," in other_fields:
self.other_fields = other_fields.split(",")
else:
self.other_fields = [other_fields]
else:
self.other_fields = other_fields

def passes(self, attribute, key, dictionary):
for field in self.other_fields:
if field in dictionary:
return required.passes(self, attribute, key, dictionary)
else:
return True

def message(self, attribute):
fields = ",".join(self.other_fields)
return "The {} is required because {} is present.".format(
attribute,
"one in {}".format(fields) if len(self.other_fields) > 1 else self.other_fields[0],
)

def negated_message(self, attribute):
return "The {} is not required because {} {} is not present.".format(
attribute,
"none of" if len(self.other_fields) > 1 else "",
",".join(self.other_fields)
)


class distinct(BaseValidation):
"""When working with list, the field under validation must not have any
duplicate values."""

def passes(self, attribute, key, dictionary):
# check if list contains duplicates
return len(set(attribute)) == len(attribute)

def message(self, attribute):
return "The {} field has duplicate values.".format(attribute)

def negated_message(self, attribute):
return "The {} field has only different values.".format(attribute)


def flatten(iterable):

flat_list = []
Expand Down Expand Up @@ -1139,6 +1255,8 @@ def __init__(self):
contains,
date,
does_not,
different,
distinct,
equals,
email,
exists,
Expand All @@ -1163,10 +1281,13 @@ def __init__(self):
postal_code,
regex,
required,
required_if,
required_with,
string,
strong,
timezone,
truthy,
uuid,
video,
when,
)
Expand Down
5 changes: 5 additions & 0 deletions src/masonite/validation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
confirmed,
contains,
date,
different,
distinct,
does_not,
email,
equals,
Expand All @@ -34,10 +36,13 @@
postal_code,
regex,
required,
required_if,
required_with,
string,
strong,
timezone,
truthy,
uuid,
video,
when,
)
Loading