From a9fd677cb3167afbe0b27bf1a8fe5a16eaad5908 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Thu, 13 Sep 2007 22:16:59 +0000 Subject: [PATCH] Fixed #5403 -- Added Dutch localflavor. Thanks, Jan Rademaker. git-svn-id: http://code.djangoproject.com/svn/django/trunk@6139 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 2 +- django/contrib/localflavor/nl/__init__.py | 0 django/contrib/localflavor/nl/forms.py | 92 +++++++++++++++++++ django/contrib/localflavor/nl/nl_provinces.py | 16 ++++ tests/regressiontests/forms/localflavor.py | 68 ++++++++++++++ 5 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 django/contrib/localflavor/nl/__init__.py create mode 100644 django/contrib/localflavor/nl/forms.py create mode 100644 django/contrib/localflavor/nl/nl_provinces.py diff --git a/AUTHORS b/AUTHORS index 9a46c37574..5067da3d0d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -237,7 +237,7 @@ answer newbie questions, and generally made Django that much better: polpak@yahoo.com Jyrki Pulliainen Johann Queuniet - J. Rademaker + Jan Rademaker Michael Radziej Amit Ramon Massimiliano Ravelli diff --git a/django/contrib/localflavor/nl/__init__.py b/django/contrib/localflavor/nl/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/contrib/localflavor/nl/forms.py b/django/contrib/localflavor/nl/forms.py new file mode 100644 index 0000000000..e202ab0595 --- /dev/null +++ b/django/contrib/localflavor/nl/forms.py @@ -0,0 +1,92 @@ +""" +NL-specific Form helpers +""" + +import re + +from django.newforms import ValidationError +from django.newforms.fields import Field, Select, EMPTY_VALUES +from django.utils.translation import ugettext as _ +from django.utils.encoding import smart_unicode + +pc_re = re.compile('^\d{4}[A-Z]{2}$') +sofi_re = re.compile('^\d{9}$') +numeric_re = re.compile('^\d+$') + +class NLZipCodeField(Field): + """ + A Dutch postal code field. + """ + def clean(self, value): + super(NLZipCodeField, self).clean(value) + if value in EMPTY_VALUES: + return u'' + + msg = _('Enter a valid postal code') + value = value.strip().upper().replace(' ', '') + if not pc_re.search(value): + raise ValidationError(msg) + + if int(value[:4]) < 1000: + raise ValidationError(msg) + + return u'%s %s' % (value[:4], value[4:]) + +class NLProvinceSelect(Select): + """ + A Select widget that uses a list of provinces of the Netherlands as its + choices. + """ + def __init__(self, attrs=None): + from nl_provinces import PROVINCE_CHOICES + super(NLProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES) + +class NLPhoneNumberField(Field): + """ + A Dutch telephone number field. + """ + def clean(self, value): + super(NLPhoneNumberField, self).clean(value) + if value in EMPTY_VALUES: + return u'' + + msg = _('Enter a valid phone number') + phone_nr = re.sub('[\-\s\(\)]', '', smart_unicode(value)) + + if len(phone_nr) == 10 and numeric_re.search(phone_nr): + return value + + if phone_nr[:3] == '+31' and len(phone_nr) == 12 and \ + numeric_re.search(phone_nr[3:]): + return value + + raise ValidationError(msg) + +class NLSoFiNumberField(Field): + """ + A Dutch social security number (SoFi/BSN) field. + + http://nl.wikipedia.org/wiki/Sofinummer + """ + def clean(self, value): + super(NLSoFiNumberField, self).clean(value) + if value in EMPTY_VALUES: + return u'' + + msg = _('Enter a valid SoFi number') + + if not sofi_re.search(value): + raise ValidationError(msg) + + if int(value) == 0: + raise ValidationError(msg) + + checksum = 0 + for i in range(9, 1, -1): + checksum += int(value[9-i]) * i + checksum -= int(value[-1]) + + if checksum % 11 != 0: + raise ValidationError(msg) + + return value diff --git a/django/contrib/localflavor/nl/nl_provinces.py b/django/contrib/localflavor/nl/nl_provinces.py new file mode 100644 index 0000000000..8964adfac0 --- /dev/null +++ b/django/contrib/localflavor/nl/nl_provinces.py @@ -0,0 +1,16 @@ +from django.utils.translation import ugettext_lazy as _ + +PROVINCE_CHOICES = ( + ('DR', _('Drente')), + ('FL', _('Flevoland')), + ('FR', _('Friesland')), + ('GL', _('Gelderland')), + ('GR', _('Groningen')), + ('LB', _('Limburg')), + ('NB', _('Noord-Brabant')), + ('NH', _('Noord-Holland')), + ('OV', _('Overijssel')), + ('UT', _('Utrecht')), + ('ZE', _('Zeeland')), + ('ZH', _('Zuid-Holland')), +) diff --git a/tests/regressiontests/forms/localflavor.py b/tests/regressiontests/forms/localflavor.py index a896013b0d..ae9ee14a92 100644 --- a/tests/regressiontests/forms/localflavor.py +++ b/tests/regressiontests/forms/localflavor.py @@ -1446,4 +1446,72 @@ ValidationError: [u'National Identification Number consists of 11 digits.'] Traceback (most recent call last): ... ValidationError: [u'National Identification Number consists of 11 digits.'] + +# NLPhoneNumberField ######################################################## + +>>> from django.contrib.localflavor.nl.forms import NLPhoneNumberField +>>> f = NLPhoneNumberField(required=False) +>>> f.clean('') +u'' +>>> f.clean('012-3456789') +'012-3456789' +>>> f.clean('0123456789') +'0123456789' +>>> f.clean('+31-12-3456789') +'+31-12-3456789' +>>> f.clean('(0123) 456789') +'(0123) 456789' +>>> f.clean('foo') +Traceback (most recent call last): + ... +ValidationError: [u'Enter a valid phone number'] + +# NLZipCodeField ############################################################ + +>>> from django.contrib.localflavor.nl.forms import NLZipCodeField +>>> f = NLZipCodeField(required=False) +>>> f.clean('') +u'' +>>> f.clean('1234ab') +u'1234 AB' +>>> f.clean('1234 ab') +u'1234 AB' +>>> f.clean('1234 AB') +u'1234 AB' +>>> f.clean('0123AB') +Traceback (most recent call last): + ... +ValidationError: [u'Enter a valid postal code'] +>>> f.clean('foo') +Traceback (most recent call last): + ... +ValidationError: [u'Enter a valid postal code'] + +# NLSoFiNumberField ######################################################### + +>>> from django.contrib.localflavor.nl.forms import NLSoFiNumberField +>>> f = NLSoFiNumberField(required=False) +>>> f.clean('') +u'' +>>> f.clean('123456782') +'123456782' +>>> f.clean('000000000') +Traceback (most recent call last): + ... +ValidationError: [u'Enter a valid SoFi number'] +>>> f.clean('123456789') +Traceback (most recent call last): + ... +ValidationError: [u'Enter a valid SoFi number'] +>>> f.clean('foo') +Traceback (most recent call last): + ... +ValidationError: [u'Enter a valid SoFi number'] + +# NLProvinceSelect ########################################################## + +>>> from django.contrib.localflavor.nl.forms import NLProvinceSelect +>>> s = NLProvinceSelect() +>>> s.render('provinces', 'OV') +u'' """