From 82b33b1d805a5565c2d8aed21340bc56c0a12679 Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Fri, 1 Jan 2010 21:32:24 +0000 Subject: [PATCH] Fixed #8068 - Added Kuwaiti (kw) localflavor. Thanks to Ahmad Al-Ibrahim for providing the patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@12042 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 1 + django/contrib/localflavor/kw/__init__.py | 0 django/contrib/localflavor/kw/forms.py | 61 +++++++++++++++++++ docs/ref/contrib/localflavor.txt | 14 +++++ tests/regressiontests/forms/localflavor/kw.py | 15 +++++ tests/regressiontests/forms/tests.py | 2 + 6 files changed, 93 insertions(+) create mode 100644 django/contrib/localflavor/kw/__init__.py create mode 100644 django/contrib/localflavor/kw/forms.py create mode 100644 tests/regressiontests/forms/localflavor/kw.py diff --git a/AUTHORS b/AUTHORS index cc459fa4b4..5593562b40 100644 --- a/AUTHORS +++ b/AUTHORS @@ -31,6 +31,7 @@ answer newbie questions, and generally made Django that much better: Andi Albrecht Marty Alchin Ahmad Alhashemi + Ahmad Al-Ibrahim Daniel Alves Barbosa de Oliveira Vaz AgarFu Dagur Páll Ammendrup diff --git a/django/contrib/localflavor/kw/__init__.py b/django/contrib/localflavor/kw/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/contrib/localflavor/kw/forms.py b/django/contrib/localflavor/kw/forms.py new file mode 100644 index 0000000000..32d6cb990a --- /dev/null +++ b/django/contrib/localflavor/kw/forms.py @@ -0,0 +1,61 @@ +""" +Kuwait-specific Form helpers +""" +import re +from datetime import date +from django.forms import ValidationError +from django.forms.fields import Field, RegexField, EMPTY_VALUES +from django.utils.translation import gettext as _ + +id_re = re.compile(r'^(?P\d{1})(?P\d\d)(?P\d\d)(?P
\d\d)(?P\d{4})(?P\d{1})') + +class KWCivilIDNumberField(Field): + """ + Kuwaiti Civil ID numbers are 12 digits, second to seventh digits + represents the person's birthdate. + + Checks the following rules to determine the validty of the number: + * The number consist of 12 digits. + * The birthdate of the person is a valid date. + * The calculated checksum equals to the last digit of the Civil ID. + """ + default_error_messages = { + 'invalid': _('Enter a valid Kuwaiti Civil ID number'), + } + + def has_valid_checksum(self, value): + weight = (2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2) + calculated_checksum = 0 + for i in range(11): + calculated_checksum += int(value[i]) * weight[i] + + remainder = calculated_checksum % 11 + checkdigit = 11 - remainder + if checkdigit != int(value[11]): + return False + return True + + def clean(self, value): + super(KWCivilIDNumberField, self).clean(value) + if value in EMPTY_VALUES: + return u'' + + if not re.match(r'^\d{12}$', value): + raise ValidationError(self.error_messages['invalid']) + + match = re.match(id_re, value) + + if not match: + raise ValidationError(self.error_messages['invalid']) + + gd = match.groupdict() + + try: + d = date(int(gd['yy']), int(gd['mm']), int(gd['dd'])) + except ValueError: + raise ValidationError(self.error_messages['invalid']) + + if not self.has_valid_checksum(value): + raise ValidationError(self.error_messages['invalid']) + + return value diff --git a/docs/ref/contrib/localflavor.txt b/docs/ref/contrib/localflavor.txt index 1eafa9fac1..0b4b9f11fb 100644 --- a/docs/ref/contrib/localflavor.txt +++ b/docs/ref/contrib/localflavor.txt @@ -52,6 +52,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are: * India_ * Italy_ * Japan_ + * Kuwait_ * Mexico_ * `The Netherlands`_ * Norway_ @@ -95,6 +96,7 @@ Here's an example of how to use them:: .. _India: `India (in\_)`_ .. _Italy: `Italy (it)`_ .. _Japan: `Japan (jp)`_ +.. _Kuwait: `Kuwait (kw)`_ .. _Mexico: `Mexico (mx)`_ .. _Norway: `Norway (no)`_ .. _Peru: `Peru (pe)`_ @@ -410,6 +412,18 @@ Japan (``jp``) A ``Select`` widget that uses a list of Japanese prefectures as its choices. +Kuwait (``kw``) +=============== + +.. class:: kw.forms.KWCivilIDNumberField + + A form field that validates input as a Kuwaiti Civil ID number. A valid + Civil ID number must obey the following rules: + + * The number consist of 12 digits. + * The birthdate of the person is a valid date. + * The calculated checksum equals to the last digit of the Civil ID. + Mexico (``mx``) =============== diff --git a/tests/regressiontests/forms/localflavor/kw.py b/tests/regressiontests/forms/localflavor/kw.py new file mode 100644 index 0000000000..265c1f00ae --- /dev/null +++ b/tests/regressiontests/forms/localflavor/kw.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Tests for the contrib/localflavor/ KW form fields. + +tests = r""" +# KWCivilIDNumberField ######################################################## + +>>> from django.contrib.localflavor.kw.forms import KWCivilIDNumberField +>>> f = KWCivilIDNumberField() +>>> f.clean('282040701483') +'282040701483' +>>> f.clean('289332013455') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid Kuwaiti Civil ID number'] +""" diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index 0c70cf49aa..bc30e3c82e 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -18,6 +18,7 @@ from localflavor.generic import tests as localflavor_generic_tests from localflavor.is_ import tests as localflavor_is_tests from localflavor.it import tests as localflavor_it_tests from localflavor.jp import tests as localflavor_jp_tests +from localflavor.kw import tests as localflavor_kw_tests from localflavor.nl import tests as localflavor_nl_tests from localflavor.pl import tests as localflavor_pl_tests from localflavor.ro import tests as localflavor_ro_tests @@ -55,6 +56,7 @@ __test__ = { 'localflavor_is_tests': localflavor_is_tests, 'localflavor_it_tests': localflavor_it_tests, 'localflavor_jp_tests': localflavor_jp_tests, + 'localflavor_kw_tests': localflavor_kw_tests, 'localflavor_nl_tests': localflavor_nl_tests, 'localflavor_pl_tests': localflavor_pl_tests, 'localflavor_ro_tests': localflavor_ro_tests,