Skip to content

Commit

Permalink
Fixed django#17864 -- Added Hong Kong localflavor. Thanks to mrkschan…
Browse files Browse the repository at this point in the history
… and Adrien Lemaire.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17886 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
jphalip committed Apr 9, 2012
1 parent 883c38c commit 6f7aa51
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 0 deletions.
Empty file.
71 changes: 71 additions & 0 deletions django/contrib/localflavor/hk/forms.py
Original file line number Diff line number Diff line change
@@ -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
10 changes: 10 additions & 0 deletions docs/ref/contrib/localflavor.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are:
* Finland_
* France_
* Germany_
* `Hong Kong`_
* Iceland_
* India_
* Indonesia_
Expand Down Expand Up @@ -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\_)`_
Expand Down Expand Up @@ -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``)
========================

Expand Down
Empty file.
11 changes: 11 additions & 0 deletions tests/regressiontests/localflavor/hk/forms.py
Original file line number Diff line number Diff line change
@@ -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
35 changes: 35 additions & 0 deletions tests/regressiontests/localflavor/hk/tests.py
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions tests/regressiontests/localflavor/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 6f7aa51

Please sign in to comment.