Validation Rules¶
The classes behind Rule-Based Validation and Live Validation. Everything here is imported from the top-level package:
from pydantic_schemaforms import FormValidator, PhoneRule, NumericRangeRule
Rules run alongside the model's own validation, never instead of it. The
built-in rules other than RequiredRule pass an empty value, so an optional
field is only checked when it's filled in. A CustomRule function is called
for empty values too.
Rule classes¶
Every rule takes message= to replace its default text.
| Rule | Checks | Arguments |
|---|---|---|
RequiredRule() |
The value is present and not blank | message |
MinLengthRule(min_length) |
At least min_length characters |
min_length, message |
MaxLengthRule(max_length) |
At most max_length characters |
max_length, message |
RegexRule(pattern) |
Matches the regular expression | pattern, message, flags |
EmailRule() |
Looks like an email address (format only) | message |
EmailDeliverabilityRule() |
The email's domain exists and accepts mail (a real DNS lookup; server only; needs the email extra) |
message, timeout (seconds) |
PhoneRule() |
Looks like a phone number: 10 to 15 digits, with optional +, spaces, dashes, dots and parentheses |
message |
NumericRangeRule(min_value, max_value) |
A number within the range; either end can be None |
min_value, max_value, message |
DateRangeRule(min_date, max_date) |
A date within the range; dates or "YYYY-MM-DD" strings |
min_date, max_date, message |
CustomRule(func) |
func(value) returns True, or (is_valid, message) |
validator_func, message |
Without message=, EmailDeliverabilityRule reports the lookup's own reason,
such as "The domain name example.invalid does not exist."
A rule on its own: PhoneRule().validate("abc") returns
(False, "Please enter a valid phone number").
FormValidator¶
A set of rules for a whole form.
| Method | Does |
|---|---|
FormValidator() (or create_validator()) |
Creates an empty set |
.field(name) |
The FieldValidator for that field, created on first use |
.add_cross_field_rule(func) |
Adds a check of the whole data. func(data) returns (is_valid, {field: message}). |
.validate(data) |
Runs every rule. Returns (is_valid, {field: [messages]}). |
FieldValidator¶
The rules of one field. Every method returns the validator, so they chain:
rules.field("username").required().min_length(3).max_length(20)
| Method | Adds |
|---|---|
.add_rule(rule) |
Any rule instance |
.required(message=None) |
RequiredRule |
.min_length(n, message=None) / .max_length(n, message=None) |
MinLengthRule / MaxLengthRule |
.email(message=None, check_deliverability=False, dns_timeout=None) |
EmailRule, plus EmailDeliverabilityRule when asked |
.email_deliverability(message=None, dns_timeout=None) |
EmailDeliverabilityRule |
.phone(message=None) |
PhoneRule |
.numeric_range(min_val=None, max_val=None, message=None) |
NumericRangeRule |
.date_range(min_date=None, max_date=None, message=None) |
DateRangeRule |
.regex(pattern, message=None) |
RegexRule |
.custom(func, message=None) |
CustomRule |
.validate(value) |
Runs the rules: (is_valid, [messages]) |
FieldValidator("email") also works on its own, and a ValidationSchema
collects several (.add_field(validator)) for a LiveValidator
(.build_live_validator()).
CrossFieldRules¶
Ready-made functions for add_cross_field_rule():
| Function | Checks |
|---|---|
CrossFieldRules.password_confirmation(password_field="password", confirm_field="confirm_password", message=...) |
The two fields match; the message goes on the confirmation |
CrossFieldRules.date_range_validation(start_field, end_field, message=...) |
The end date is after the start date; the message goes on the end date |
Single-value checks¶
| Function | Returns |
|---|---|
create_email_validator(check_deliverability=False, dns_timeout=None) |
A function that checks one email and returns a ValidationResponse |
create_password_strength_validator(min_length=8) |
A function that checks a password's length and mix of characters, with warnings and suggestions |
ValidationResponse has field_name, is_valid, errors, warnings,
suggestions, value and formatted_value, plus to_dict() and to_json().
DeliverableEmailStr¶
An EmailStr type that also does the DNS check as part of Pydantic
validation, so a model field is enough:
from pydantic_schemaforms import DeliverableEmailStr, Field, FormModel
class SignupForm(FormModel):
email: DeliverableEmailStr = Field(title="Email")
validate(), as_api_model() and LiveValidator.for_model() all apply it.
LiveValidator¶
Checks fields on the server as the user types; the Live Validation page shows the whole setup.
| Member | Does |
|---|---|
LiveValidator.for_model(*models, debounce_ms=600, config=None) |
A validator that checks each field of the given models against their own types and constraints |
.register_field_validator(validator) |
Adds a FieldValidator's rules for its field |
.register_schema(schema) |
Adds every field of a ValidationSchema |
.register_model_validator(Model) |
Adds every field of another model, for several forms on one validator |
.validate_field(name, value) |
Checks one value: a ValidationResponse |
.render_field_with_live_validation(...) |
Renders one input wired to the validation endpoint |
.render_htmx_script() |
The script tag that loads HTMX for the page |
HTMXValidationConfig sets when checks run and how results look:
validate_on_blur (default True), validate_on_change (True),
validate_on_input (False), debounce_ms (300), the CSS classes
(success_class, error_class, warning_class, loading_class) and
whether to show success, warnings and suggestions.
validation_response_headers() returns the response headers an endpoint
should send with a check's result.