Code

Ticket #14349: be_localflavor.2.diff

File be_localflavor.2.diff, 15.3 KB (added by laurentluce, 4 years ago)

add support for 0xxxxxxxx, 04xxxxxxxx phone number format. Wrap long lines.

Line 
1Index: django/contrib/localflavor/be/be_regions.py
2===================================================================
3--- django/contrib/localflavor/be/be_regions.py (revision 0)
4+++ django/contrib/localflavor/be/be_regions.py (revision 0)
5@@ -0,0 +1,10 @@
6+# -*- coding: utf-8 -*-
7+from django.utils.translation import ugettext_lazy as _
8+
9+# ISO codes
10+REGION_CHOICES = (
11+    ('BRU', _('Brussels Capital Region')),
12+    ('VLG', _('Flemish Region')),
13+    ('WAL', _('Wallonia'))
14+)
15+
16Index: django/contrib/localflavor/be/be_provinces.py
17===================================================================
18--- django/contrib/localflavor/be/be_provinces.py       (revision 0)
19+++ django/contrib/localflavor/be/be_provinces.py       (revision 0)
20@@ -0,0 +1,18 @@
21+# -*- coding: utf-8 -*-
22+from django.utils.translation import ugettext_lazy as _
23+
24+# ISO codes
25+PROVINCE_CHOICES = (
26+    ('VAN', _('Antwerp')),
27+    ('BRU', _('Brussels')),
28+    ('VOV', _('East Flanders')),
29+    ('VBR', _('Flemish Brabant')),
30+    ('WHT', _('Hainaut')),
31+    ('WLG', _('Liege')),
32+    ('VLI', _('Limburg')),
33+    ('WLX', _('Luxembourg')),
34+    ('WNA', _('Namur')),
35+    ('WBR', _('Walloon Brabant')),
36+    ('VWV', _('West Flanders'))
37+)
38+
39Index: django/contrib/localflavor/be/__init__.py
40===================================================================
41Index: django/contrib/localflavor/be/forms.py
42===================================================================
43--- django/contrib/localflavor/be/forms.py      (revision 0)
44+++ django/contrib/localflavor/be/forms.py      (revision 0)
45@@ -0,0 +1,69 @@
46+# -*- coding: utf-8 -*-
47+"""
48+Belgium-specific Form helpers
49+"""
50+
51+from django.core.validators import EMPTY_VALUES
52+from django.forms import ValidationError
53+from django.forms.fields import RegexField, Select
54+from django.utils.translation import ugettext_lazy as _
55+import re
56+
57+class BEPostalCodeField(RegexField):
58+    """
59+    A form field that validates its input as a belgium postal code.
60+   
61+    Belgium postal code is a 4 digits string. The first digit indicates
62+    the province (except for the 3ddd numbers that are shared by the
63+    eastern part of Flemish Brabant and Limburg and the and 1ddd that
64+    are shared by the Brussels Capital Region, the western part of
65+    Flemish Brabant and Walloon Brabant)
66+    """
67+    default_error_messages = {
68+        'invalid': _('Enter a valid postal code in the range and \
69+            format 1XXX - 9XXX.'),
70+    }
71+
72+    def __init__(self, *args, **kwargs):
73+        super(BEPostalCodeField, self).__init__(
74+                r'^[1-9]\d{3}$',
75+                max_length=None, min_length=None, *args, **kwargs)
76+
77+class BEPhoneNumberField(RegexField):
78+    """
79+    A form field that validates its input as a belgium phone number.
80+
81+    Landlines have a seven-digit subscriber number and a one-digit area code,
82+    while smaller cities have a six-digit subscriber number and a two-digit
83+    area code. Cell phones have a six-digit subscriber number and a two-digit
84+    area code preceeded by the number 4.
85+    0d ddd dd dd, 0d/ddd.dd.dd, 0dddddddd - dialling a bigger city
86+    0dd dd dd dd, 0dd/dd.dd.dd, 0dddddddd - dialling a smaller city
87+    04dd ddd dd dd, 04dd/ddd.dd.dd, 04ddddddddd - dialling a mobile number
88+    """
89+    default_error_messages = {
90+        'invalid': _('Enter a valid phone number in one of the formats \
91+0x xxx xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, \
92+04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.'),
93+    }
94+
95+    def __init__(self, *args, **kwargs):
96+        super(BEPhoneNumberField, self).__init__(r'^[0]\d{1}[/. ]?\d{3}[. ]\d{2}[. ]?\d{2}$|^[0]\d{2}[/. ]?\d{2}[. ]?\d{2}[. ]?\d{2}$|^[0][4]\d{2}[/. ]?\d{2}[. ]?\d{2}[. ]?\d{2}$',
97+            max_length=None, min_length=None, *args, **kwargs)
98+
99+class BERegionSelect(Select):
100+    """
101+    A Select widget that uses a list of belgium regions as its choices.
102+    """
103+    def __init__(self, attrs=None):
104+        from be_regions import REGION_CHOICES
105+        super(BERegionSelect, self).__init__(attrs, choices=REGION_CHOICES)
106+
107+class BEProvinceSelect(Select):
108+    """
109+    A Select widget that uses a list of belgium provinces as its choices.
110+    """
111+    def __init__(self, attrs=None):
112+        from be_provinces import PROVINCE_CHOICES
113+        super(BEProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
114+
115Index: tests/regressiontests/forms/tests.py
116===================================================================
117--- tests/regressiontests/forms/tests.py        (revision 13957)
118+++ tests/regressiontests/forms/tests.py        (working copy)
119@@ -5,6 +5,7 @@
120 from localflavor.ar import tests as localflavor_ar_tests
121 from localflavor.at import tests as localflavor_at_tests
122 from localflavor.au import tests as localflavor_au_tests
123+from localflavor.be import tests as localflavor_be_tests
124 from localflavor.br import tests as localflavor_br_tests
125 from localflavor.ca import tests as localflavor_ca_tests
126 from localflavor.ch import tests as localflavor_ch_tests
127@@ -50,6 +51,7 @@
128     'localflavor_ar_tests': localflavor_ar_tests,
129     'localflavor_at_tests': localflavor_at_tests,
130     'localflavor_au_tests': localflavor_au_tests,
131+    'localflavor_be_tests': localflavor_be_tests,
132     'localflavor_br_tests': localflavor_br_tests,
133     'localflavor_ca_tests': localflavor_ca_tests,
134     'localflavor_ch_tests': localflavor_ch_tests,
135Index: tests/regressiontests/forms/localflavor/be.py
136===================================================================
137--- tests/regressiontests/forms/localflavor/be.py       (revision 0)
138+++ tests/regressiontests/forms/localflavor/be.py       (revision 0)
139@@ -0,0 +1,190 @@
140+# -*- coding: utf-8 -*-
141+# Tests for the contrib/localflavor/ BE form fields.
142+
143+tests = r"""
144+# BEPostalCodeField ##############################################################
145+
146+BEPostalCodeField validates that data is a four-digit belgium postal code following the regex ^[1-9](/d){3}$.
147+>>> from django.contrib.localflavor.be.forms import BEPostalCodeField
148+>>> f = BEPostalCodeField()
149+>>> f.clean('1451')
150+u'1451'
151+>>> f.clean('2540')
152+u'2540'
153+>>> f.clean('0287')
154+Traceback (most recent call last):
155+...
156+ValidationError: [u'Enter a valid postal code in the range and format 1XXX - 9XXX.']
157+>>> f.clean('14309')
158+Traceback (most recent call last):
159+...
160+ValidationError: [u'Enter a valid postal code in the range and format 1XXX - 9XXX.']
161+>>> f.clean('873')
162+Traceback (most recent call last):
163+...
164+ValidationError: [u'Enter a valid postal code in the range and format 1XXX - 9XXX.']
165+>>> f.clean('35 74')
166+Traceback (most recent call last):
167+...
168+ValidationError: [u'Enter a valid postal code in the range and format 1XXX - 9XXX.']
169+>>> f.clean('859A')
170+Traceback (most recent call last):
171+...
172+ValidationError: [u'Enter a valid postal code in the range and format 1XXX - 9XXX.']
173+>>> f.clean('')
174+Traceback (most recent call last):
175+...
176+ValidationError: [u'This field is required.']
177+
178+>>> f = BEPostalCodeField(required=False)
179+>>> f.clean('1451')
180+u'1451'
181+>>> f.clean('2540')
182+u'2540'
183+>>> f.clean('0287')
184+Traceback (most recent call last):
185+...
186+ValidationError: [u'Enter a valid postal code in the range and format 1XXX - 9XXX.']
187+>>> f.clean('14309')
188+Traceback (most recent call last):
189+...
190+ValidationError: [u'Enter a valid postal code in the range and format 1XXX - 9XXX.']
191+>>> f.clean('873')
192+Traceback (most recent call last):
193+...
194+ValidationError: [u'Enter a valid postal code in the range and format 1XXX - 9XXX.']
195+>>> f.clean('35 74')
196+Traceback (most recent call last):
197+...
198+ValidationError: [u'Enter a valid postal code in the range and format 1XXX - 9XXX.']
199+>>> f.clean('859A')
200+Traceback (most recent call last):
201+...
202+ValidationError: [u'Enter a valid postal code in the range and format 1XXX - 9XXX.']
203+>>> f.clean('')
204+u''
205+
206+# BEPhoneNumberField ##############################################################
207+
208+BEPhoneNumberField validates that data follows: Landlines have a seven-digit subscriber number and a one-digit area code, while smaller cities have a six-digit subscriber number and a two-digit area code. Cell phones have a six-digit subscriber number and a two-digit area code preceeded by the number 4.
209+0d ddd dd dd, 0d/ddd.dd.dd - dialling a bigger city
210+0dd dd dd dd, 0dd/dd.dd.dd - dialling a smaller city
211+04dd dd dd dd, 04dd/dd.dd.dd - dialling a mobile number
212+
213+>>> from django.contrib.localflavor.be.forms import BEPhoneNumberField
214+>>> f = BEPhoneNumberField()
215+>>> f.clean('01 234 56 78')
216+u'01 234 56 78'
217+>>> f.clean('01/234.56.78')
218+u'01/234.56.78'
219+>>> f.clean('012 34 56 78')
220+u'012 34 56 78'
221+>>> f.clean('012/34.56.78')
222+u'012/34.56.78'
223+>>> f.clean('0412 34 56 78')
224+u'0412 34 56 78'
225+>>> f.clean('0412/34.56.78')
226+u'0412/34.56.78'
227+>>> f.clean('012345678')
228+u'012345678'
229+>>> f.clean('0412345678')
230+u'0412345678'
231+>>> f.clean('01234567')
232+Traceback (most recent call last):
233+...
234+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
235+>>> f.clean('12/345.67.89')
236+Traceback (most recent call last):
237+...
238+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
239+>>> f.clean('012/345.678.90')
240+Traceback (most recent call last):
241+...
242+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
243+>>> f.clean('012/34.56.789')
244+Traceback (most recent call last):
245+...
246+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
247+>>> f.clean('0123/45.67.89')
248+Traceback (most recent call last):
249+...
250+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
251+>>> f.clean('012/345 678 90')
252+Traceback (most recent call last):
253+...
254+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
255+>>> f.clean('012/34 56 789')
256+Traceback (most recent call last):
257+...
258+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
259+>>> f.clean('')
260+Traceback (most recent call last):
261+...
262+ValidationError: [u'This field is required.']
263+
264+>>> f = BEPhoneNumberField(required=False)
265+>>> f.clean('01 234 56 78')
266+u'01 234 56 78'
267+>>> f.clean('01/234.56.78')
268+u'01/234.56.78'
269+>>> f.clean('012 34 56 78')
270+u'012 34 56 78'
271+>>> f.clean('012/34.56.78')
272+u'012/34.56.78'
273+>>> f.clean('0412 34 56 78')
274+u'0412 34 56 78'
275+>>> f.clean('0412/34.56.78')
276+u'0412/34.56.78'
277+>>> f.clean('012345678')
278+u'012345678'
279+>>> f.clean('0412345678')
280+u'0412345678'
281+>>> f.clean('12345678')
282+Traceback (most recent call last):
283+...
284+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
285+>>> f.clean('12/345.67.89')
286+Traceback (most recent call last):
287+...
288+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
289+>>> f.clean('012/345.678.90')
290+Traceback (most recent call last):
291+...
292+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
293+>>> f.clean('012/34.56.789')
294+Traceback (most recent call last):
295+...
296+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
297+>>> f.clean('0123/45.67.89')
298+Traceback (most recent call last):
299+...
300+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
301+>>> f.clean('012/345 678 90')
302+Traceback (most recent call last):
303+...
304+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
305+>>> f.clean('012/34 56 789')
306+Traceback (most recent call last):
307+...
308+ValidationError: [u'Enter a valid phone number in one of the formats 0x xxx   xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, 04xx/xx.xx.xx, 0xxxxxxxx, 04xxxxxxxx.']
309+>>> f.clean('')
310+u''
311+
312+# BERegionSelect ##############################################################
313+
314+BERegionSelect is a Select widget that uses a list of belgium regions as its choices.
315+>>> from django.contrib.localflavor.be.forms import BERegionSelect
316+>>> w = BERegionSelect()
317+>>> w.render('regions', 'VLG')
318+u'<select name="regions">\n<option value="BRU">Brussels Capital Region</option>\n<option value="VLG" selected="selected">Flemish Region</option>\n<option value="WAL">Wallonia</option>\n</select>'
319+
320+# BEProvinceSelect ##############################################################
321+
322+BEProvinceSelect is a Select widget that uses a list of Belgium provinces as its choices.
323+>>> from django.contrib.localflavor.be.forms import BEProvinceSelect
324+>>> w = BEProvinceSelect()
325+>>> w.render('provinces', 'WLG')
326+u'<select name="provinces">\n<option value="VAN">Antwerp</option>\n<option value="BRU">Brussels</option>\n<option value="VOV">East Flanders</option>\n<option value="VBR">Flemish Brabant</option>\n<option value="WHT">Hainaut</option>\n<option value="WLG" selected="selected">Liege</option>\n<option value="VLI">Limburg</option>\n<option value="WLX">Luxembourg</option>\n<option value="WNA">Namur</option>\n<option value="WBR">Walloon Brabant</option>\n<option value="VWV">West Flanders</option>\n</select>'
327+
328+"""
329+
330Index: docs/ref/contrib/localflavor.txt
331===================================================================
332--- docs/ref/contrib/localflavor.txt    (revision 13957)
333+++ docs/ref/contrib/localflavor.txt    (working copy)
334@@ -39,6 +39,7 @@
335     * Argentina_
336     * Australia_
337     * Austria_
338+    * Belgium_
339     * Brazil_
340     * Canada_
341     * Chile_
342@@ -85,6 +86,7 @@
343 .. _Argentina: `Argentina (ar)`_
344 .. _Australia: `Australia (au)`_
345 .. _Austria: `Austria (at)`_
346+.. _Belgium: `Belgium (be)`_
347 .. _Brazil: `Brazil (br)`_
348 .. _Canada: `Canada (ca)`_
349 .. _Chile: `Chile (cl)`_
350@@ -182,6 +184,30 @@
351 
352     A form field that validates its input as an Austrian social security number.
353 
354+Belgium (``be``)
355+===============
356+
357+.. class:: be.forms.BEPhoneNumberField
358+
359+    A form field that validates input as a Belgium phone number, with one of
360+    the formats 0x xxx xx xx, 0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx,
361+    0xx/xx.xx.xx, 04xx/xx.xx.xx.
362+
363+.. class:: be.forms.BEPostalCodeField
364+
365+    A form field that validates input as a Belgium postal code, in the range
366+    and format 1XXX-9XXX.
367+
368+.. class:: be.forms.BEProvinceSelect
369+
370+    A ``Select`` widget that uses a list of Belgium provinces as its
371+    choices.
372+
373+.. class:: be.forms.BERegionSelect
374+
375+    A ``Select`` widget that uses a list of Belgium regions as its
376+    choices.
377+
378 Brazil (``br``)
379 ===============
380