Ticket #3890: us_ssnfield.diff

File us_ssnfield.diff, 2.4 KB (added by ubernostrum, 8 years ago)

Patch adding USSocialSecurityNumberField

  • django/contrib/localflavor/usa/forms.py

     
    99import re
    1010
    1111phone_digits_re = re.compile(r'^(?:1-?)?(\d{3})[-\.]?(\d{3})[-\.]?(\d{4})$')
     12ssn_re = re.compile(r"^(?P<area>\d{3})-(?P<group>\d{2})-(?P<serial>\d{4})$")
    1213
    1314class USZipCodeField(RegexField):
    1415    def __init__(self, *args, **kwargs):
     
    2829            return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
    2930        raise ValidationError(u'Phone numbers must be in XXX-XXX-XXXX format.')
    3031
     32class USSocialSecurityNumberField(Field):
     33    """
     34    A United States Social Security number.
     35   
     36    Checks the following rules to determine whether the number is valid:
     37   
     38        * Conforms to the XXX-XX-XXXX format.
     39        * No group consists entirely of zeroes.
     40        * The leading group is not "666" (block "666" will never be allocated).
     41        * The number is not in the promotional block 987-65-4320 through 987-65-4329,
     42          which are permanently invalid.
     43        * The number is not one known to be invalid due to otherwise widespread
     44          promotional use or distribution (e.g., the Woolworth's number or the 1962
     45          promotional number).
     46   
     47    """
     48    def clean(self, value):
     49        super(USSocialSecurityNumberField, self).clean(value)
     50        if value in EMPTY_VALUES:
     51            return u''
     52        msg = gettext(u'Enter a valid US Social Security number in XXX-XX-XXXX format')
     53        match = re.match(ssn_re, value)
     54        if not match:
     55            raise ValidationError(msg)
     56        area, group, serial = match.groupdict()['area'], match.groupdict()['group'], match.groupdict()['serial']
     57       
     58        # First pass: no blocks of all zeroes.
     59        if area == '000' or \
     60           group == '00' or \
     61           serial == '0000':
     62            raise ValidationError(msg)
     63       
     64        # Second pass: promotional and otherwise permanently invalid numbers.
     65        if area == '666' or \
     66           (area == '987' and group == '65' and \
     67            4320 <= int(serial) <= 4329) or \
     68           value == '078-05-1120' or \
     69           value == '219-09-9999':
     70            raise ValidationError(msg)
     71        return value
     72
    3173class USStateField(Field):
    3274    """
    3375    A form field that validates its input is a U.S. state name or abbreviation.
Back to Top