from django.forms import ValidationError from django.forms.fields import Field, EMPTY_VALUES from django.utils.encoding import smart_unicode from django.utils.translation import ugettext_lazy as _ import re import types class UKPhoneNumberField(Field): default_error_messages = { 'partial': _('Phone number must include an area code.'), 'non_uk': _('Phone number must be a UK number.'), 'length_range': _('Phone number must be between %d and %d digits'), 'length': _('Phone number must be %d digits'), 'reject_premium': _('Phone number can\'t be premium rate.'), 'reject_service': _('Phone number can\'t be a service number.') } number_specs = ( (r'^01(1\d|\d1)', None, (4, 3, 4)), (r'^016977\d{4}$', None, (6, 4)), (r'^01(3873|5(242|39[456])|697[347]|768[347]|9467)', None, (6, 5)), (r'^01', None, (5, (5, 6))), (r'^0500\d{6}$', None, (4, 6)), (r'^0(2[03489]|5[56])', None, (3, 4, 4)), (r'^03[0347]', None, (4, 3, 4)), (r'^07([1-57-9]|624)', None, (5, 6)), (r'^070', 'premium', (3, 6)), (r'^08(001111|454647)$', None, (4, 4)), (r'^0800\d{6}$', None, (4, 6)), (r'^08[047]\d{8}$', None, (4, 3, 4)), (r'^09', 'premium', (4, 3, 4)), (r'^11[68]', 'service', (3, 3)), (r'^999$', 'service', (3,)), (r'^1', 'service', None), ) def __init__(self, *args, **kwargs): self.reject = set(kwargs.pop('reject', ())) super(UKPhoneNumberField, self).__init__(*args, **kwargs) def clean(self, value): super(UKPhoneNumberField, self).clean(value) value = smart_unicode(value) if value in EMPTY_VALUES: return u'' value = re.sub(r'[^0-9+]', r'', value) value = re.sub(r'(? max_length: return False return True def format_number(self, value, number_spec): if number_spec[1] is None: components = (value,) else: components = [] position = 0 last_index = len(number_spec) - 1 for index, chunk in enumerate(number_spec[1]): if index == last_index: components.append(value[position:]) else: components.append(value[position:position+chunk]) position += chunk return ' '.join(components)