Author: jezdez
Date: 2011-07-03 10:56:15 -0700 (Sun, 03 Jul 2011)
New Revision: 16495

Modified:
   django/trunk/django/contrib/localflavor/in_/forms.py
   django/trunk/docs/ref/contrib/localflavor.txt
   django/trunk/tests/regressiontests/forms/localflavor/in_.py
Log:
Fixed #14608 -- Added phone number field to Indian local flavor. Thanks, lawgon 
and Julien Phalip.

Modified: django/trunk/django/contrib/localflavor/in_/forms.py
===================================================================
--- django/trunk/django/contrib/localflavor/in_/forms.py        2011-07-03 
17:56:05 UTC (rev 16494)
+++ django/trunk/django/contrib/localflavor/in_/forms.py        2011-07-03 
17:56:15 UTC (rev 16495)
@@ -5,11 +5,32 @@
 
 from django.core.validators import EMPTY_VALUES
 from django.forms import ValidationError
-from django.forms.fields import Field, RegexField, Select
+from django.forms.fields import Field, RegexField, CharField, Select
 from django.utils.encoding import smart_unicode
 from django.utils.translation import ugettext_lazy as _
 
+phone_digits_re = re.compile(r"""
+(
+    (?P<std_code>                   # the std-code group
+        ^0                          # all std-codes start with 0
+        (
+            (?P<twodigit>\d{2})   | # either two, three or four digits
+            (?P<threedigit>\d{3}) | # following the 0
+            (?P<fourdigit>\d{4})
+        )
+    )
+    [-\s]                           # space or -
+    (?P<phone_no>                   # the phone number group
+        [1-6]                       # first digit of phone number
+        (
+            (?(twodigit)\d{7})   |  # 7 more phone digits for 3 digit stdcode
+            (?(threedigit)\d{6}) |  # 6 more phone digits for 4 digit stdcode
+            (?(fourdigit)\d{5})     # 5 more phone digits for 5 digit stdcode
+        )
+    )
+)$""", re.VERBOSE)
 
+
 class INZipCodeField(RegexField):
     default_error_messages = {
         'invalid': _(u'Enter a zip code in the format XXXXXX or XXX XXX.'),
@@ -27,6 +48,7 @@
         value = re.sub(r'^(\d{3})\s(\d{3})$', r'\1\2', value)
         return value
 
+
 class INStateField(Field):
     """
     A form field that validates its input is a Indian state name or
@@ -53,6 +75,7 @@
                 pass
         raise ValidationError(self.error_messages['invalid'])
 
+
 class INStateSelect(Select):
     """
     A Select widget that uses a list of Indian states/territories as its
@@ -62,3 +85,28 @@
         from in_states import STATE_CHOICES
         super(INStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
 
+
+class INPhoneNumberField(CharField):
+    """
+    INPhoneNumberField validates that the data is a valid Indian phone number,
+    including the STD code. It's normalised to 0XXX-XXXXXXX or 0XXX XXXXXXX
+    format. The first string is the STD code which is a '0' followed by 2-4
+    digits. The second string is 8 digits if the STD code is 3 digits, 7
+    digits if the STD code is 4 digits and 6 digits if the STD code is 5
+    digits. The second string will start with numbers between 1 and 6. The
+    separator is either a space or a hyphen.
+    """
+    default_error_messages = {
+        'invalid': _('Phone numbers must be in 02X-8X or 03X-7X or 04X-6X 
format.'),
+    }
+
+    def clean(self, value):
+        super(INPhoneNumberField, self).clean(value)
+        if value in EMPTY_VALUES:
+            return u''
+        value = smart_unicode(value)
+        m = phone_digits_re.match(value)
+        if m:
+            return u'%s' % (value)
+        raise ValidationError(self.error_messages['invalid'])
+

Modified: django/trunk/docs/ref/contrib/localflavor.txt
===================================================================
--- django/trunk/docs/ref/contrib/localflavor.txt       2011-07-03 17:56:05 UTC 
(rev 16494)
+++ django/trunk/docs/ref/contrib/localflavor.txt       2011-07-03 17:56:15 UTC 
(rev 16495)
@@ -576,22 +576,34 @@
 India (``in_``)
 ===============
 
-.. class:: in.forms.INStateField
+.. class:: in_.forms.INStateField
 
     A form field that validates input as an Indian state/territory name or
     abbreviation. Input is normalized to the standard two-letter vehicle
     registration abbreviation for the given state or territory.
 
-.. class:: in.forms.INZipCodeField
+.. class:: in_.forms.INZipCodeField
 
     A form field that validates input as an Indian zip code, with the
     format XXXXXXX.
 
-.. class:: in.forms.INStateSelect
+.. class:: in_.forms.INStateSelect
 
     A ``Select`` widget that uses a list of Indian states/territories as its
     choices.
 
+.. versionadded:: 1.4
+
+.. class:: in_.forms.INPhoneNumberField
+
+    A form field that validates that the data is a valid Indian phone number,
+    including the STD code. It's normalised to 0XXX-XXXXXXX or 0XXX XXXXXXX
+    format. The first string is the STD code which is a '0' followed by 2-4
+    digits. The second string is 8 digits if the STD code is 3 digits, 7
+    digits if the STD code is 4 digits and 6 digits if the STD code is 5
+    digits. The second string will start with numbers between 1 and 6. The
+    separator is either a space or a hyphen.
+
 Ireland (``ie``)
 ================
 

Modified: django/trunk/tests/regressiontests/forms/localflavor/in_.py
===================================================================
--- django/trunk/tests/regressiontests/forms/localflavor/in_.py 2011-07-03 
17:56:05 UTC (rev 16494)
+++ django/trunk/tests/regressiontests/forms/localflavor/in_.py 2011-07-03 
17:56:15 UTC (rev 16495)
@@ -1,12 +1,32 @@
 import warnings
 
 from django.contrib.localflavor.in_.forms import (INZipCodeField,
-                                                  INStateField, INStateSelect)
+    INStateField, INStateSelect, INPhoneNumberField)
 
 from utils import LocalFlavorTestCase
 
 
+
 class INLocalFlavorTests(LocalFlavorTestCase):
+    def test_INPhoneNumberField(self):
+        error_format = [u'Phone numbers must be in 02X-8X or 03X-7X or 04X-6X 
format.']
+        valid = {
+            '0423-2443667': '0423-2443667',
+            '0423 2443667': '0423 2443667',
+            '04236-244366': '04236-244366',
+            '040-24436678': '040-24436678',
+        }
+        invalid = {
+            '04-2443667': error_format,
+            '423-2443667': error_format,
+            '0423-9442667': error_format,
+            '0423-0443667': error_format,
+            '0423-244366': error_format,
+            '04232442667': error_format,
+            '0423DJANGO': error_format,
+        }
+        self.assertFieldOutput(INPhoneNumberField, valid, invalid)
+
     def test_INPStateSelect(self):
         f = INStateSelect()
         out = u'''<select name="state">

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to