Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4910 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit a5938f350ca65fdfbe22050c1a04ba8a99e87854 1 parent b6264d0
@malcolmt malcolmt authored
View
42 django/contrib/localflavor/usa/forms.py
@@ -9,6 +9,7 @@
import re
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):
def __init__(self, *args, **kwargs):
@@ -28,6 +29,47 @@ def clean(self, value):
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 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):
"""
A form field that validates its input is a U.S. state name or abbreviation.
View
12 tests/regressiontests/forms/localflavor.py
@@ -246,6 +246,18 @@
<option value="WY">Wyoming</option>
</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 validates that the data is a valid UK postcode.
Please sign in to comment.
Something went wrong with that request. Please try again.