Skip to content

Custom Rules

Spotlight provides a variety of helpful validation rules; however, you may wish to specify some of your own.

Tip

Instead of creating a custom rule, you can also use a function as a rule.

Both functions as a rule and custom rules provide great reusability. Functions offer more simplicity, but lack support for the use of rule parameters.

Specifications

To create a custom rule, create a class that inherits from the Rule class. A rule is required to have the following specifications:

  • A rule should have a name attribute.
  • A rule should implement the passes() method which contains the logic that determines if a value passes the rule.
  • A rule should have a message property.

Example

Here is an example of an uppercase rule:

from spotlight import Rule


class UppercaseRule(Rule):
    """Uppercase"""

    name = "uppercase"

    def passes(self, field: str, value: Any, parameters: List[str], validator) -> bool:
        self.message_fields = dict(field=field)

        return value.upper() == value

    @property
    def message(self) -> str:
        return "The {field} field must be uppercase."

As shown in the example above, the passes() method will receive the following arguments:

  • field -- name of the field under validation
  • value -- value of the field under validation
  • parameters -- list of rule parameters
  • validator -- instance of the validator

After creating a custom rule it has to be registered with the validator:

from custom_rules import UppercaseRule

validator = Validator()
validator.register_rule(UppercaseRule())

After registering the rule, it can be used:

rules = {
    "test": "uppercase"
}

data = {
    "test": "HELLO WORLD!"
}

Attributes

In addition to the name attribute, a rule has 2 additional attributes which are set to False by default: implicit & stop. These attributes may be overwritten.

Implicit

Setting implicit to True will cause the field under validation to be validated against the rule even if the field is not present. This is useful for rules such as required.

Stop

Setting stop to True causes the validator to stop validating the rest of the rules specified for the current field if the current rule fails.

Message Fields

If a rule contains a message property that contains keyword arguments (words surrounded by curly braces) like the one in the example below, the message_fields variable needs to be set in the passes method.

@property
def message(self) -> str:
    return "The {field} field must be uppercase."

The message_fields variable can be set as shown in the example below. The keyword arguments in the message property will be replaced with the values from the message_fields dictionary.

def passes(self, field: str, value: Any, parameters: List[str], validator) -> bool:
    self.message_fields = dict(field=field)