summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2007-12-02 18:43:01 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2007-12-02 18:43:01 +0000
commit61947f0635bdf5a4043caa2562e085058b2d19a8 (patch)
tree6491aa7c8284b04559e194861b26856e6c2547e3
parent805c364fcf52f69498e15ddd8960baa3e4bc6d34 (diff)
Fixed #3961 -- Added South African localflavor. Thanks, Russell Cloran.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@6843 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/contrib/localflavor/za/__init__.py0
-rw-r--r--django/contrib/localflavor/za/forms.py57
-rw-r--r--django/contrib/localflavor/za/za_provinces.py13
-rw-r--r--tests/regressiontests/forms/localflavor/za.py40
-rw-r--r--tests/regressiontests/forms/tests.py2
5 files changed, 112 insertions, 0 deletions
diff --git a/django/contrib/localflavor/za/__init__.py b/django/contrib/localflavor/za/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/django/contrib/localflavor/za/__init__.py
diff --git a/django/contrib/localflavor/za/forms.py b/django/contrib/localflavor/za/forms.py
new file mode 100644
index 0000000000..b04b7cf6ab
--- /dev/null
+++ b/django/contrib/localflavor/za/forms.py
@@ -0,0 +1,57 @@
+"""
+South Africa-specific Form helpers
+"""
+
+from django.newforms import ValidationError
+from django.newforms.fields import Field, RegexField, EMPTY_VALUES
+from django.utils.checksums import luhn
+from django.utils.translation import gettext as _
+import re
+from datetime import date
+
+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})')
+
+class ZAIDField(Field):
+ """A form field for South African ID numbers -- the checksum is validated
+ using the Luhn checksum, and uses a simlistic (read: not entirely accurate)
+ check for the birthdate
+ """
+
+ def __init__(self, *args, **kwargs):
+ super(ZAIDField, self).__init__()
+ self.error_message = _(u'Enter a valid South African ID number')
+
+ def clean(self, value):
+ # strip spaces and dashes
+ value = value.strip().replace(' ', '').replace('-', '')
+
+ super(ZAIDField, self).clean(value)
+
+ if value in EMPTY_VALUES:
+ return u''
+
+ match = re.match(id_re, value)
+
+ if not match:
+ raise ValidationError(self.error_message)
+
+ g = match.groupdict()
+
+ try:
+ # The year 2000 is conveniently a leapyear.
+ # This algorithm will break in xx00 years which aren't leap years
+ # There is no way to guess the century of a ZA ID number
+ d = date(int(g['yy']) + 2000, int(g['mm']), int(g['dd']))
+ except ValueError:
+ raise ValidationError(self.error_message)
+
+ if not luhn(value):
+ raise ValidationError(self.error_message)
+
+ return value
+
+class ZAPostCodeField(RegexField):
+ def __init__(self, *args, **kwargs):
+ super(ZAPostCodeField, self).__init__(r'^\d{4}$',
+ max_length=None, min_length=None,
+ error_message=_(u'Enter a valid South African postal code'))
diff --git a/django/contrib/localflavor/za/za_provinces.py b/django/contrib/localflavor/za/za_provinces.py
new file mode 100644
index 0000000000..0bc6fe14b3
--- /dev/null
+++ b/django/contrib/localflavor/za/za_provinces.py
@@ -0,0 +1,13 @@
+from django.utils.translation import gettext_lazy as _
+
+PROVINCE_CHOICES = (
+ ('EC', _('Eastern Cape')),
+ ('FS', _('Free State')),
+ ('GP', _('Gauteng')),
+ ('KN', _('KwaZulu-Natal')),
+ ('LP', _('Limpopo')),
+ ('MP', _('Mpumalanga')),
+ ('NC', _('Northern Cape')),
+ ('NW', _('North West')),
+ ('WC', _('Western Cape')),
+)
diff --git a/tests/regressiontests/forms/localflavor/za.py b/tests/regressiontests/forms/localflavor/za.py
new file mode 100644
index 0000000000..a948964b8d
--- /dev/null
+++ b/tests/regressiontests/forms/localflavor/za.py
@@ -0,0 +1,40 @@
+tests = r"""
+# ZAIDField #################################################################
+
+ZAIDField validates that the date is a valid birthdate and that the value
+has a valid checksum. It allows spaces and dashes, and returns a plain
+string of digits.
+>>> from django.contrib.localflavor.za.forms import ZAIDField
+>>> f = ZAIDField()
+>>> f.clean('0002290001003')
+'0002290001003'
+>>> f.clean('000229 0001 003')
+'0002290001003'
+>>> f.clean('0102290001001')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid South African ID number']
+>>> f.clean('811208')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid South African ID number']
+>>> f.clean('0002290001004')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid South African ID number']
+
+# ZAPostCodeField ###########################################################
+>>> from django.contrib.localflavor.za.forms import ZAPostCodeField
+>>> f = ZAPostCodeField()
+>>> f.clean('abcd')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid South African postal code']
+>>> f.clean('0000')
+u'0000'
+>>> f.clean(' 7530')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid South African postal code']
+
+"""
diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py
index 6acd4f2e1d..bb0e30b874 100644
--- a/tests/regressiontests/forms/tests.py
+++ b/tests/regressiontests/forms/tests.py
@@ -22,6 +22,7 @@ from localflavor.pl import tests as localflavor_pl_tests
from localflavor.sk import tests as localflavor_sk_tests
from localflavor.uk import tests as localflavor_uk_tests
from localflavor.us import tests as localflavor_us_tests
+from localflavor.za import tests as localflavor_za_tests
from regressions import tests as regression_tests
from util import tests as util_tests
from widgets import tests as widgets_tests
@@ -50,6 +51,7 @@ __test__ = {
'localflavor_sk_tests': localflavor_sk_tests,
'localflavor_uk_tests': localflavor_uk_tests,
'localflavor_us_tests': localflavor_us_tests,
+ 'localflavor_za_tests': localflavor_za_tests,
'regression_tests': regression_tests,
'util_tests': util_tests,
'widgets_tests': widgets_tests,