From 6f7aa51b2c3fbcbbc76404cee3cbe511feabaf1f Mon Sep 17 00:00:00 2001 From: Julien Phalip Date: Mon, 9 Apr 2012 17:25:02 +0000 Subject: [PATCH] Fixed #17864 -- Added Hong Kong localflavor. Thanks to mrkschan and Adrien Lemaire. git-svn-id: http://code.djangoproject.com/svn/django/trunk@17886 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/localflavor/hk/__init__.py | 0 django/contrib/localflavor/hk/forms.py | 71 +++++++++++++++++++ docs/ref/contrib/localflavor.txt | 10 +++ .../localflavor/hk/__init__.py | 0 tests/regressiontests/localflavor/hk/forms.py | 11 +++ tests/regressiontests/localflavor/hk/tests.py | 35 +++++++++ tests/regressiontests/localflavor/tests.py | 1 + 7 files changed, 128 insertions(+) create mode 100644 django/contrib/localflavor/hk/__init__.py create mode 100644 django/contrib/localflavor/hk/forms.py create mode 100644 tests/regressiontests/localflavor/hk/__init__.py create mode 100644 tests/regressiontests/localflavor/hk/forms.py create mode 100644 tests/regressiontests/localflavor/hk/tests.py diff --git a/django/contrib/localflavor/hk/__init__.py b/django/contrib/localflavor/hk/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/contrib/localflavor/hk/forms.py b/django/contrib/localflavor/hk/forms.py new file mode 100644 index 0000000000..852ef7d4b2 --- /dev/null +++ b/django/contrib/localflavor/hk/forms.py @@ -0,0 +1,71 @@ +""" +Hong Kong specific Form helpers +""" +from __future__ import absolute_import + +import re + +from django.core.validators import EMPTY_VALUES +from django.forms import CharField +from django.forms import ValidationError +from django.utils.encoding import smart_unicode +from django.utils.translation import ugettext_lazy as _ + + +hk_phone_digits_re = re.compile(r'^(?:852-?)?(\d{4})[-\.]?(\d{4})$') +hk_special_numbers = ('999', '992', '112') +hk_phone_prefixes = ('2', '3', '5', '6', '8', '9') +hk_formats = ['XXXX-XXXX', '852-XXXX-XXXX', '(+852) XXXX-XXXX', + 'XXXX XXXX', 'XXXXXXXX'] + + + +class HKPhoneNumberField(CharField): + """ + Validate Hong Kong phone number. + The input format can be either one of the followings: + 'XXXX-XXXX', '852-XXXX-XXXX', '(+852) XXXX-XXXX', + 'XXXX XXXX', or 'XXXXXXXX'. + The output format is 'XXXX-XXXX'. + + Note: The phone number shall not start with 999, 992, or 112. + And, it should start with either 2, 3, 5, 6, 8, or 9. + + Ref - http://en.wikipedia.org/wiki/Telephone_numbers_in_Hong_Kong + """ + default_error_messages = { + 'disguise': _('Phone number should not start with ' \ + 'one of the followings: %s.' % \ + ', '.join(hk_special_numbers)), + 'invalid': _('Phone number must be in one of the following formats: ' + '%s.' % ', '.join(hk_formats)), + 'prefix': _('Phone number should start with ' \ + 'one of the followings: %s.' % \ + ', '.join(hk_phone_prefixes)), + } + + def __init__(self, *args, **kwargs): + super(HKPhoneNumberField, self).__init__(*args, **kwargs) + + def clean(self, value): + super(HKPhoneNumberField, self).clean(value) + + if value in EMPTY_VALUES: + return u'' + + value = re.sub('(\(|\)|\s+|\+)', '', smart_unicode(value)) + m = hk_phone_digits_re.search(value) + if not m: + raise ValidationError(self.error_messages['invalid']) + + value = u'%s-%s' % (m.group(1), m.group(2)) + for special in hk_special_numbers: + if value.startswith(special): + raise ValidationError(self.error_messages['disguise']) + + prefix_found = map(lambda prefix: value.startswith(prefix), + hk_phone_prefixes) + if not any(prefix_found): + raise ValidationError(self.error_messages['prefix']) + + return value diff --git a/docs/ref/contrib/localflavor.txt b/docs/ref/contrib/localflavor.txt index 8ad8b8e9d6..61c8c7ae47 100644 --- a/docs/ref/contrib/localflavor.txt +++ b/docs/ref/contrib/localflavor.txt @@ -51,6 +51,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are: * Finland_ * France_ * Germany_ +* `Hong Kong`_ * Iceland_ * India_ * Indonesia_ @@ -108,6 +109,7 @@ Here's an example of how to use them:: .. _Finland: `Finland (fi)`_ .. _France: `France (fr)`_ .. _Germany: `Germany (de)`_ +.. _Hong Kong: `Hong Kong (hk)`_ .. _The Netherlands: `The Netherlands (nl)`_ .. _Iceland: `Iceland (is\_)`_ .. _India: `India (in\_)`_ @@ -560,6 +562,14 @@ Germany (``de``) A ``Select`` widget that uses a list of German states as its choices. +Hong Kong (``hk``) +================== + +.. class:: hk.forms.HKPhoneNumberField + + A form field that validates input as a Hong Kong phone number. + + The Netherlands (``nl``) ======================== diff --git a/tests/regressiontests/localflavor/hk/__init__.py b/tests/regressiontests/localflavor/hk/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regressiontests/localflavor/hk/forms.py b/tests/regressiontests/localflavor/hk/forms.py new file mode 100644 index 0000000000..a6233d4245 --- /dev/null +++ b/tests/regressiontests/localflavor/hk/forms.py @@ -0,0 +1,11 @@ +from __future__ import absolute_import + +from django.forms import ModelForm + +from .models import HKPlace + + +class HKPlaceForm(ModelForm): + + class Meta: + model = HKPlace diff --git a/tests/regressiontests/localflavor/hk/tests.py b/tests/regressiontests/localflavor/hk/tests.py new file mode 100644 index 0000000000..ed5e623ee2 --- /dev/null +++ b/tests/regressiontests/localflavor/hk/tests.py @@ -0,0 +1,35 @@ +from __future__ import absolute_import + +from django.contrib.localflavor.hk.forms import HKPhoneNumberField +from django.test import SimpleTestCase + + +class HKLocalFlavorTests(SimpleTestCase): + """Tests for Hong Kong Local Flavors""" + + def test_HKPhoneNumberField(self): + error_msgs = HKPhoneNumberField.default_error_messages + valid = { + '2111-1111': '2111-1111', + '3111 1111': '3111-1111', + '51111111': '5111-1111', + '852-6111-1111': '6111-1111', + '(+852) 8111-1111': '8111-1111', + '(+852) 9111-1111': '9111-1111', + '85291111111': '9111-1111', + } + invalid = { + '9991-1111': [error_msgs['disguise'], ], + '9921-1111': [error_msgs['disguise'], ], + '1121-1111': [error_msgs['disguise'], ], + '99987654': [error_msgs['disguise'], ], + '99287654': [error_msgs['disguise'], ], + '11287654': [error_msgs['disguise'], ], + '1': [error_msgs['invalid'], ], + '2111--1111': [error_msgs['invalid'], ], + '11111111': [error_msgs['prefix'], ], + '00000000': [error_msgs['prefix'], ], + '44444444': [error_msgs['prefix'], ], + '77777777': [error_msgs['prefix'], ], + } + self.assertFieldOutput(HKPhoneNumberField, valid, invalid) diff --git a/tests/regressiontests/localflavor/tests.py b/tests/regressiontests/localflavor/tests.py index 0062a4f925..856e518bed 100644 --- a/tests/regressiontests/localflavor/tests.py +++ b/tests/regressiontests/localflavor/tests.py @@ -18,6 +18,7 @@ from .fi.tests import FILocalFlavorTests from .fr.tests import FRLocalFlavorTests from .gb.tests import GBLocalFlavorTests from .generic.tests import GenericLocalFlavorTests +from .hk.tests import HKLocalFlavorTests from .hr.tests import HRLocalFlavorTests from .id.tests import IDLocalFlavorTests from .ie.tests import IELocalFlavorTests