HH/apps/core/validators.py
2026-07-19 12:27:55 +03:00

46 lines
1.4 KiB
Python

"""
Shared validators used across multiple apps.
"""
import re
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
# Regex for a Saudi mobile number after stripping spaces/dashes/parens/plus.
# Accepts any of:
# 05XXXXXXXX (10 digits, local with trunk 0)
# 5XXXXXXXX (9 digits, no trunk)
# 9665XXXXXXXX (12 digits, country code without +)
# +9665XXXXXXXX (13 digits, country code with +)
SAUDI_MOBILE_REGEX = re.compile(r"^(?:\+?966|0)?5\d{8}$")
# HTML5 form pattern equivalent (HTML anchors ^...$ implicitly).
# Exposed for reuse in widget attrs and template <input pattern="...">.
SAUDI_PHONE_HTML_PATTERN = r"(\+?966|0)?5[0-9]{8}"
def validate_saudi_phone(value):
"""
Validate that ``value`` is a Saudi mobile number.
Accepts the following formats (spaces, dashes and parentheses are ignored):
05XXXXXXXX
5XXXXXXXX
9665XXXXXXXX
+9665XXXXXXXX
Stored value is returned unchanged (no normalization).
Raises ``ValidationError`` if the number is not a valid Saudi mobile.
"""
if value is None or value == "":
return value
cleaned = re.sub(r"[\s\-()]", "", str(value))
if not SAUDI_MOBILE_REGEX.match(cleaned):
raise ValidationError(
_("Please enter a valid Saudi mobile number "
"(e.g. 05XXXXXXXX or +9665XXXXXXXX)."),
code="invalid_saudi_phone",
)
return value