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
This commit is contained in:
Julien Phalip 2012-04-09 17:25:02 +00:00
parent 883c38c499
commit 6f7aa51b2c
7 changed files with 128 additions and 0 deletions

View File

@ -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 File

@ -51,6 +51,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are:
* Finland_ * Finland_
* France_ * France_
* Germany_ * Germany_
* `Hong Kong`_
* Iceland_ * Iceland_
* India_ * India_
* Indonesia_ * Indonesia_
@ -108,6 +109,7 @@ Here's an example of how to use them::
.. _Finland: `Finland (fi)`_ .. _Finland: `Finland (fi)`_
.. _France: `France (fr)`_ .. _France: `France (fr)`_
.. _Germany: `Germany (de)`_ .. _Germany: `Germany (de)`_
.. _Hong Kong: `Hong Kong (hk)`_
.. _The Netherlands: `The Netherlands (nl)`_ .. _The Netherlands: `The Netherlands (nl)`_
.. _Iceland: `Iceland (is\_)`_ .. _Iceland: `Iceland (is\_)`_
.. _India: `India (in\_)`_ .. _India: `India (in\_)`_
@ -560,6 +562,14 @@ Germany (``de``)
A ``Select`` widget that uses a list of German states as its choices. 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``) The Netherlands (``nl``)
======================== ========================

View File

@ -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 File

@ -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 File

@ -18,6 +18,7 @@ from .fi.tests import FILocalFlavorTests
from .fr.tests import FRLocalFlavorTests from .fr.tests import FRLocalFlavorTests
from .gb.tests import GBLocalFlavorTests from .gb.tests import GBLocalFlavorTests
from .generic.tests import GenericLocalFlavorTests from .generic.tests import GenericLocalFlavorTests
from .hk.tests import HKLocalFlavorTests
from .hr.tests import HRLocalFlavorTests from .hr.tests import HRLocalFlavorTests
from .id.tests import IDLocalFlavorTests from .id.tests import IDLocalFlavorTests
from .ie.tests import IELocalFlavorTests from .ie.tests import IELocalFlavorTests