Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Ticket #18775 - Fixed the Romanian phone number field validation rules #275

Closed
wants to merge 2 commits into from

3 participants

Daniel Ursache Dogariu Adrian Holovaty Simon Charette
Daniel Ursache Dogariu

The previous version only supported 10 digit phone numbers.

This branch adds validation for:

  • normal phone numbers: 0xxxxxxxxx
  • geographic short phone numbers: 0xxxxxx
  • national short phone numbers: 1xx, 1xxxxx

I ran the Django test suite and all tests pass (under SQLite).

Original ticket: https://code.djangoproject.com/ticket/18775

django/contrib/localflavor/ro/forms.py
((10 lines not shown))
173 181
     default_error_messages = {
174  
-        'invalid': _('Phone numbers must be in XXXX-XXXXXX format.'),
  182
+        'invalid_length': 
  183
+            _('Phone numbers may only have 7 or 10 digits, except the ' +
  184
+                'national short numbers which have 3 or 6 digits'),
  185
+        'invalid_long_format': 
  186
+            _('Normal phone numbers (7 or 10 digits) must begin with \"0\"'),
1
Simon Charette Owner
charettes added a note

Are those backslashes really needed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
django/contrib/localflavor/ro/forms.py
((10 lines not shown))
173 181
     default_error_messages = {
174  
-        'invalid': _('Phone numbers must be in XXXX-XXXXXX format.'),
  182
+        'invalid_length': 
  183
+            _('Phone numbers may only have 7 or 10 digits, except the ' +
  184
+                'national short numbers which have 3 or 6 digits'),
  185
+        'invalid_long_format': 
  186
+            _('Normal phone numbers (7 or 10 digits) must begin with \"0\"'),
  187
+        'invalid_short_format': 
  188
+            _('National short numbers (3 or 6 digits) must begin with \"1\"'),
1
Simon Charette Owner
charettes added a note

Idem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
django/contrib/localflavor/ro/forms.py
((19 lines not shown))
175 189
     }
176 190
 
177  
-    def __init__(self, max_length=20, min_length=10, *args, **kwargs):
178  
-        super(ROPhoneNumberField, self).__init__(r'^[0-9\-\(\)\s]{10,20}$',
  191
+    def __init__(self, max_length=20, min_length=3, *args, **kwargs):
  192
+        super(ROPhoneNumberField, self).__init__(r'^[0-9\-\.\(\)\s]{3,20}$',
1
Simon Charette Owner
charettes added a note

It might be worth compiling the regexp in the class or module level and reuse.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
django/contrib/localflavor/ro/forms.py
((5 lines not shown))
191 206
         value = value.replace(' ','')
192  
-        if len(value) != 10:
193  
-            raise ValidationError(self.error_messages['invalid'])
  207
+        length = len(value)
  208
+        if length in [3, 6, 7, 10]:
1
Simon Charette Owner
charettes added a note

This should be a tuple.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Daniel Ursache Dogariu

Thanks for the tips. I will update the code and resubmit the rquest.

Adrian Holovaty

Hey there -- django.contrib.localflavor is now deprecated, and we're not making any more changes to it. Could you reopen this pull request for the shiny new package django-localflavor-ro? Here's the link: https://github.com/django/django-localflavor-ro

Sorry we didn't get to this pull request before the deprecation. I hope it's not too much of a pain to migrate this to the new package.

Adrian Holovaty adrianholovaty closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
43  django/contrib/localflavor/ro/forms.py
@@ -3,6 +3,7 @@
3 3
 Romanian specific form helpers.
4 4
 """
5 5
 from __future__ import absolute_import, unicode_literals
  6
+import re
6 7
 
7 8
 from django.contrib.localflavor.ro.ro_counties import COUNTIES_CHOICES
8 9
 from django.core.validators import EMPTY_VALUES
@@ -10,6 +11,9 @@
10 11
 from django.utils.translation import ugettext_lazy as _
11 12
 
12 13
 
  14
+phone_digits_re = re.compile(r'^[0-9\-\.\(\)\s]{3,20}$')
  15
+
  16
+
13 17
 class ROCIFField(RegexField):
14 18
     """
15 19
     A Romanian fiscal identity code (CIF) field
@@ -47,6 +51,7 @@ def clean(self, value):
47 51
             raise ValidationError(self.error_messages['invalid'])
48 52
         return value[::-1]
49 53
 
  54
+
50 55
 class ROCNPField(RegexField):
51 56
     """
52 57
     A Romanian personal identity code (CNP) field
@@ -87,6 +92,7 @@ def clean(self, value):
87 92
             raise ValidationError(self.error_messages['invalid'])
88 93
         return value
89 94
 
  95
+
90 96
 class ROCountyField(Field):
91 97
     """
92 98
     A form field that validates its input is a Romanian county name or
@@ -124,6 +130,7 @@ def clean(self, value):
124 130
                 return entry[0]
125 131
         raise ValidationError(self.error_messages['invalid'])
126 132
 
  133
+
127 134
 class ROCountySelect(Select):
128 135
     """
129 136
     A Select widget that uses a list of Romanian counties (judete) as its
@@ -132,6 +139,7 @@ class ROCountySelect(Select):
132 139
     def __init__(self, attrs=None):
133 140
         super(ROCountySelect, self).__init__(attrs, choices=COUNTIES_CHOICES)
134 141
 
  142
+
135 143
 class ROIBANField(RegexField):
136 144
     """
137 145
     Romanian International Bank Account Number (IBAN) field
@@ -155,6 +163,7 @@ def clean(self, value):
155 163
             return ''
156 164
         value = value.replace('-','')
157 165
         value = value.replace(' ','')
  166
+
158 167
         value = value.upper()
159 168
         if value[0:2] != 'RO':
160 169
             raise ValidationError(self.error_messages['invalid'])
@@ -168,19 +177,28 @@ def clean(self, value):
168 177
             raise ValidationError(self.error_messages['invalid'])
169 178
         return value
170 179
 
  180
+
171 181
 class ROPhoneNumberField(RegexField):
172  
-    """Romanian phone number field"""
  182
+    """
  183
+    Romanian phone number field
  184
+    """
173 185
     default_error_messages = {
174  
-        'invalid': _('Phone numbers must be in XXXX-XXXXXX format.'),
  186
+        'invalid_length': 
  187
+            _('Phone numbers may only have 7 or 10 digits, except the ' +
  188
+                'national short numbers which have 3 or 6 digits'),
  189
+        'invalid_long_format': 
  190
+            _('Normal phone numbers (7 or 10 digits) must begin with "0"'),
  191
+        'invalid_short_format': 
  192
+            _('National short numbers (3 or 6 digits) must begin with "1"'),
175 193
     }
176 194
 
177  
-    def __init__(self, max_length=20, min_length=10, *args, **kwargs):
178  
-        super(ROPhoneNumberField, self).__init__(r'^[0-9\-\(\)\s]{10,20}$',
  195
+    def __init__(self, max_length=20, min_length=3, *args, **kwargs):
  196
+        super(ROPhoneNumberField, self).__init__(phone_digits_re,
179 197
                 max_length, min_length, *args, **kwargs)
180 198
 
181 199
     def clean(self, value):
182 200
         """
183  
-        Strips -, (, ) and spaces. Checks the final length.
  201
+        Strips braces, dashes, dots and spaces. Checks the final length.
184 202
         """
185 203
         value = super(ROPhoneNumberField, self).clean(value)
186 204
         if value in EMPTY_VALUES:
@@ -188,11 +206,21 @@ def clean(self, value):
188 206
         value = value.replace('-','')
189 207
         value = value.replace('(','')
190 208
         value = value.replace(')','')
  209
+        value = value.replace('.','')
191 210
         value = value.replace(' ','')
192  
-        if len(value) != 10:
193  
-            raise ValidationError(self.error_messages['invalid'])
  211
+        length = len(value)
  212
+        if length in (3, 6, 7, 10):
  213
+            if (length == 7 or length == 10) and value[0] != '0':
  214
+                raise ValidationError(
  215
+                    self.error_messages['invalid_long_format'])    
  216
+            elif (length == 3 or length == 6) and value[0] != '1':
  217
+                raise ValidationError(
  218
+                    self.error_messages['invalid_short_format'])    
  219
+        else:
  220
+            raise ValidationError(self.error_messages['invalid_length'])
194 221
         return value
195 222
 
  223
+
196 224
 class ROPostalCodeField(RegexField):
197 225
     """Romanian postal code field."""
198 226
     default_error_messages = {
@@ -202,4 +230,3 @@ class ROPostalCodeField(RegexField):
202 230
     def __init__(self, max_length=6, min_length=6, *args, **kwargs):
203 231
         super(ROPostalCodeField, self).__init__(r'^[0-9][0-8][0-9]{4}$',
204 232
                 max_length, min_length, *args, **kwargs)
205  
-
25  tests/regressiontests/localflavor/ro/tests.py
@@ -116,16 +116,27 @@ def test_ROIBANField(self):
116 116
         self.assertFieldOutput(ROIBANField, valid, invalid)
117 117
 
118 118
     def test_ROPhoneNumberField(self):
119  
-        error_format = ['Phone numbers must be in XXXX-XXXXXX format.']
120  
-        error_atleast = ['Ensure this value has at least 10 characters (it has 9).']
121  
-        error_invalid = ['Phone numbers must be in XXXX-XXXXXX format.']
  119
+        error_invalid_length = ['Phone numbers may only have 7 or 10 digits,' +
  120
+            ' except the national short numbers which have 3 or 6 digits']
  121
+        error_invalid_long_format = ['Normal phone numbers (7 or 10 digits)' + 
  122
+            ' must begin with "0"']
  123
+        error_invalid_short_format = ['National short numbers (3 or 6 digits)' +
  124
+            ' must begin with "1"']
122 125
         valid = {
123  
-            '0264485936': '0264485936',
124  
-            '(0264)-485936': '0264485936',
  126
+            '112': '112',
  127
+            '123.456': '123456',
  128
+            '0232 987': '0232987',
  129
+            '0319876543': '0319876543',
  130
+            '031-987-6543': '0319876543',
  131
+            '(0232) 987 654': '0232987654',
125 132
         }
126 133
         invalid = {
127  
-            '02644859368': error_format,
128  
-            '026448593': error_atleast + error_invalid,
  134
+            '312': error_invalid_short_format,
  135
+            '723.456': error_invalid_short_format,
  136
+            '4232 987': error_invalid_long_format,
  137
+            '4319876543': error_invalid_long_format,
  138
+            '12345': error_invalid_length,
  139
+            '0232 987 6543': error_invalid_length,
129 140
         }
130 141
         self.assertFieldOutput(ROPhoneNumberField, valid, invalid)
131 142
 
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.