46 lines
1.4 KiB
Python
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
|