Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #17864 -- Added Hong Kong localflavor. Thanks to mrkschan and A…

…drien Lemaire.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17886 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 6f7aa51b2c3fbcbbc76404cee3cbe511feabaf1f 1 parent 883c38c
@jphalip jphalip authored
View
0  django/contrib/localflavor/hk/__init__.py
No changes.
View
71 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
View
10 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``)
========================
View
0  tests/regressiontests/localflavor/hk/__init__.py
No changes.
View
11 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
View
35 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)
View
1  tests/regressiontests/localflavor/tests.py
@@ -18,6 +18,7 @@
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
Please sign in to comment.
Something went wrong with that request. Please try again.