Fixed #3890 -- Added USSocialSecurityNumberField. Thanks James Bennet.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4910 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-04-03 03:56:17 +00:00
parent b6264d0452
commit a5938f350c
2 changed files with 54 additions and 0 deletions

View File

@ -9,6 +9,7 @@ from django.utils.translation import gettext
import re import re
phone_digits_re = re.compile(r'^(?:1-?)?(\d{3})[-\.]?(\d{3})[-\.]?(\d{4})$') phone_digits_re = re.compile(r'^(?:1-?)?(\d{3})[-\.]?(\d{3})[-\.]?(\d{4})$')
ssn_re = re.compile(r"^(?P<area>\d{3})[-\ ]?(?P<group>\d{2})[-\ ]?(?P<serial>\d{4})$")
class USZipCodeField(RegexField): class USZipCodeField(RegexField):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -28,6 +29,47 @@ class USPhoneNumberField(Field):
return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3)) 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.') raise ValidationError(u'Phone numbers must be in XXX-XXX-XXXX format.')
class USSocialSecurityNumberField(Field):
"""
A United States Social Security number.
Checks the following rules to determine whether the number is valid:
* Conforms to the XXX-XX-XXXX format.
* No group consists entirely of zeroes.
* The leading group is not "666" (block "666" will never be allocated).
* The number is not in the promotional block 987-65-4320 through 987-65-4329,
which are permanently invalid.
* The number is not one known to be invalid due to otherwise widespread
promotional use or distribution (e.g., the Woolworth's number or the 1962
promotional number).
"""
def clean(self, value):
super(USSocialSecurityNumberField, self).clean(value)
if value in EMPTY_VALUES:
return u''
msg = gettext(u'Enter a valid US Social Security number in XXX-XX-XXXX format')
match = re.match(ssn_re, value)
if not match:
raise ValidationError(msg)
area, group, serial = match.groupdict()['area'], match.groupdict()['group'], match.groupdict()['serial']
# First pass: no blocks of all zeroes.
if area == '000' or \
group == '00' or \
serial == '0000':
raise ValidationError(msg)
# Second pass: promotional and otherwise permanently invalid numbers.
if area == '666' or \
(area == '987' and group == '65' and \
4320 <= int(serial) <= 4329) or \
value == '078-05-1120' or \
value == '219-09-9999':
raise ValidationError(msg)
return u'%s-%s-%s' % (area, group, serial)
class USStateField(Field): class USStateField(Field):
""" """
A form field that validates its input is a U.S. state name or abbreviation. A form field that validates its input is a U.S. state name or abbreviation.

View File

@ -246,6 +246,18 @@ as its choices.
<option value="WY">Wyoming</option> <option value="WY">Wyoming</option>
</select> </select>
# USSocialSecurityNumberField #################################################
>>> from django.contrib.localflavor.usa.forms import USSocialSecurityNumberField
>>> f = USSocialSecurityNumberField()
>>> f.clean('987-65-4330')
u'987-65-4330'
>>> f.clean('987654330')
u'987-65-4330'
>>> f.clean('078-05-1120')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid US Social Security number in XXX-XX-XXXX format']
# UKPostcodeField ############################################################# # UKPostcodeField #############################################################
UKPostcodeField validates that the data is a valid UK postcode. UKPostcodeField validates that the data is a valid UK postcode.