Add Django-1.2.1
[frozenviper.git] / Django-1.2.1 / django / contrib / localflavor / za / forms.py
blob9a54f1ecb271fc70e49d6009ff2237f4344b10bb
1 """
2 South Africa-specific Form helpers
3 """
5 from django.core.validators import EMPTY_VALUES
6 from django.forms import ValidationError
7 from django.forms.fields import Field, RegexField
8 from django.utils.checksums import luhn
9 from django.utils.translation import gettext as _
10 import re
11 from datetime import date
13 id_re = re.compile(r'^(?P<yy>\d\d)(?P<mm>\d\d)(?P<dd>\d\d)(?P<mid>\d{4})(?P<end>\d{3})')
15 class ZAIDField(Field):
16 """A form field for South African ID numbers -- the checksum is validated
17 using the Luhn checksum, and uses a simlistic (read: not entirely accurate)
18 check for the birthdate
19 """
20 default_error_messages = {
21 'invalid': _(u'Enter a valid South African ID number'),
24 def clean(self, value):
25 # strip spaces and dashes
26 value = value.strip().replace(' ', '').replace('-', '')
28 super(ZAIDField, self).clean(value)
30 if value in EMPTY_VALUES:
31 return u''
33 match = re.match(id_re, value)
35 if not match:
36 raise ValidationError(self.error_messages['invalid'])
38 g = match.groupdict()
40 try:
41 # The year 2000 is conveniently a leapyear.
42 # This algorithm will break in xx00 years which aren't leap years
43 # There is no way to guess the century of a ZA ID number
44 d = date(int(g['yy']) + 2000, int(g['mm']), int(g['dd']))
45 except ValueError:
46 raise ValidationError(self.error_messages['invalid'])
48 if not luhn(value):
49 raise ValidationError(self.error_messages['invalid'])
51 return value
53 class ZAPostCodeField(RegexField):
54 default_error_messages = {
55 'invalid': _(u'Enter a valid South African postal code'),
58 def __init__(self, *args, **kwargs):
59 super(ZAPostCodeField, self).__init__(r'^\d{4}$',
60 max_length=None, min_length=None)