import re from django.core.validators import RegexValidator from django.utils.translation import gettext_lazy as _ PHONE_NUMBER_REGEX = re.compile(r'^(?:1\d{10}|\+852\d{8}|\+853\d{8})$') def normalize_phone_number(phone): """Normalize supported phone numbers before validation and persistence. Mainland China numbers keep the legacy 11-digit representation so existing accounts remain addressable without a data migration. Hong Kong and Macao numbers use E.164 representation to keep them globally unambiguous. """ if phone is None: return None phone = re.sub(r'[\s()-]+', '', str(phone).strip()) if phone.startswith('00'): phone = '+{}'.format(phone[2:]) if re.fullmatch(r'\+861\d{10}', phone): return phone[3:] return phone class PhoneNumberValidator(RegexValidator): regex = PHONE_NUMBER_REGEX message = _('invalid phone number')