From 08e406d146904988c8dac366a6007b7291b9642a Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 21 Feb 2007 05:54:09 +0000 Subject: [PATCH] Added newforms USPhoneNumberField in django.contrib.localflavor.usa git-svn-id: http://code.djangoproject.com/svn/django/trunk@4554 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/localflavor/usa/forms.py | 19 +++++++ tests/regressiontests/forms/tests.py | 69 +++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/django/contrib/localflavor/usa/forms.py b/django/contrib/localflavor/usa/forms.py index 4d2cb5e90a..9106519743 100644 --- a/django/contrib/localflavor/usa/forms.py +++ b/django/contrib/localflavor/usa/forms.py @@ -4,7 +4,11 @@ USA-specific Form helpers from django.newforms import ValidationError from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES +from django.newforms.util import smart_unicode from django.utils.translation import gettext +import re + +phone_digits_re = re.compile(r'^(?:1-?)?(\d{3})[-\.]?(\d{3})[-\.]?(\d{4})$') class USZipCodeField(RegexField): def __init__(self, *args, **kwargs): @@ -13,6 +17,21 @@ class USZipCodeField(RegexField): error_message=gettext(u'Enter a zip code in the format XXXXX or XXXXX-XXXX.'), *args, **kwargs) +class USPhoneNumberField(Field): + def __init__(self, allow_letters=True, *args, **kwargs): + self.allow_letters = allow_letters + super(USPhoneNumberField, self).__init__(*args, **kwargs) + + def clean(self, value): + super(USPhoneNumberField, self).clean(value) + if value in EMPTY_VALUES: + return u'' + value = re.sub('(\(|\)|\s+)', '', smart_unicode(value)) + m = phone_digits_re.search(value) + if m: + return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3)) + raise ValidationError(u'Phone numbers must be in XXX-XXX-XXXX format.') + class USStateField(Field): """ A form field that validates its input is a U.S. state name or abbreviation. diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index 7b5aa136e8..db3969429e 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -3329,6 +3329,75 @@ u'' >>> f.clean('') u'' +# USPhoneNumberField ########################################################## + +USPhoneNumberField validates that the data is a valid U.S. phone number, +including the area code. It's normalized to XXX-XXX-XXXX format. +>>> from django.contrib.localflavor.usa.forms import USPhoneNumberField +>>> f = USPhoneNumberField() +>>> f.clean('312-555-1212') +u'312-555-1212' +>>> f.clean('3125551212') +u'312-555-1212' +>>> f.clean('312 555-1212') +u'312-555-1212' +>>> f.clean('(312) 555-1212') +u'312-555-1212' +>>> f.clean('312 555 1212') +u'312-555-1212' +>>> f.clean('312.555.1212') +u'312-555-1212' +>>> f.clean('312.555-1212') +u'312-555-1212' +>>> f.clean(' (312) 555.1212 ') +u'312-555-1212' +>>> f.clean('555-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean('312-55-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean(None) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] + +>>> f = USPhoneNumberField(required=False) +>>> f.clean('312-555-1212') +u'312-555-1212' +>>> f.clean('3125551212') +u'312-555-1212' +>>> f.clean('312 555-1212') +u'312-555-1212' +>>> f.clean('(312) 555-1212') +u'312-555-1212' +>>> f.clean('312 555 1212') +u'312-555-1212' +>>> f.clean('312.555.1212') +u'312-555-1212' +>>> f.clean('312.555-1212') +u'312-555-1212' +>>> f.clean(' (312) 555.1212 ') +u'312-555-1212' +>>> f.clean('555-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean('312-55-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean(None) +u'' +>>> f.clean('') +u'' + # USStateField ################################################################ USStateField validates that the data is either an abbreviation or name of a