Fixed #14349 -- Added Belgium localflavor. Thanks for the report and patch, Laurent Luce.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14160 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2010-10-11 23:35:23 +00:00
parent d739737015
commit 6ddfe26932
7 changed files with 219 additions and 0 deletions

View File

@ -0,0 +1,16 @@
from django.utils.translation import ugettext_lazy as _
# ISO codes
PROVINCE_CHOICES = (
('VAN', _('Antwerp')),
('BRU', _('Brussels')),
('VOV', _('East Flanders')),
('VBR', _('Flemish Brabant')),
('WHT', _('Hainaut')),
('WLG', _('Liege')),
('VLI', _('Limburg')),
('WLX', _('Luxembourg')),
('WNA', _('Namur')),
('WBR', _('Walloon Brabant')),
('VWV', _('West Flanders'))
)

View File

@ -0,0 +1,8 @@
from django.utils.translation import ugettext_lazy as _
# ISO codes
REGION_CHOICES = (
('BRU', _('Brussels Capital Region')),
('VLG', _('Flemish Region')),
('WAL', _('Wallonia'))
)

View File

@ -0,0 +1,71 @@
"""
Belgium-specific Form helpers
"""
import re
from django.core.validators import EMPTY_VALUES
from django.forms import ValidationError
from django.forms.fields import RegexField, Select
from django.utils.translation import ugettext_lazy as _
class BEPostalCodeField(RegexField):
"""
A form field that validates its input as a belgium postal code.
Belgium postal code is a 4 digits string. The first digit indicates
the province (except for the 3ddd numbers that are shared by the
eastern part of Flemish Brabant and Limburg and the and 1ddd that
are shared by the Brussels Capital Region, the western part of
Flemish Brabant and Walloon Brabant)
"""
default_error_messages = {
'invalid': _(
'Enter a valid postal code in the range and format 1XXX - 9XXX.'),
}
def __init__(self, *args, **kwargs):
super(BEPostalCodeField, self).__init__(r'^[1-9]\d{3}$',
max_length=None, min_length=None, *args, **kwargs)
class BEPhoneNumberField(RegexField):
"""
A form field that validates its input as a belgium phone number.
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.
0d ddd dd dd, 0d/ddd.dd.dd, 0d.ddd.dd.dd,
0dddddddd - dialling a bigger city
0dd dd dd dd, 0dd/dd.dd.dd, 0dd.dd.dd.dd,
0dddddddd - dialling a smaller city
04dd ddd dd dd, 04dd/ddd.dd.dd,
04dd.ddd.dd.dd, 04ddddddddd - dialling a mobile number
"""
default_error_messages = {
'invalid': _('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, '
'0x.xxx.xx.xx, 0xx.xx.xx.xx, 04xx.xx.xx.xx, '
'0xxxxxxxx or 04xxxxxxxx.'),
}
def __init__(self, *args, **kwargs):
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}$',
max_length=None, min_length=None, *args, **kwargs)
class BERegionSelect(Select):
"""
A Select widget that uses a list of belgium regions as its choices.
"""
def __init__(self, attrs=None):
from be_regions import REGION_CHOICES
super(BERegionSelect, self).__init__(attrs, choices=REGION_CHOICES)
class BEProvinceSelect(Select):
"""
A Select widget that uses a list of belgium provinces as its choices.
"""
def __init__(self, attrs=None):
from be_provinces import PROVINCE_CHOICES
super(BEProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)

View File

@ -39,6 +39,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are:
* Argentina_ * Argentina_
* Australia_ * Australia_
* Austria_ * Austria_
* Belgium_
* Brazil_ * Brazil_
* Canada_ * Canada_
* Chile_ * Chile_
@ -85,6 +86,7 @@ Here's an example of how to use them::
.. _Argentina: `Argentina (ar)`_ .. _Argentina: `Argentina (ar)`_
.. _Australia: `Australia (au)`_ .. _Australia: `Australia (au)`_
.. _Austria: `Austria (at)`_ .. _Austria: `Austria (at)`_
.. _Belgium: `Belgium (be)`_
.. _Brazil: `Brazil (br)`_ .. _Brazil: `Brazil (br)`_
.. _Canada: `Canada (ca)`_ .. _Canada: `Canada (ca)`_
.. _Chile: `Chile (cl)`_ .. _Chile: `Chile (cl)`_
@ -182,6 +184,33 @@ Austria (``at``)
A form field that validates its input as an Austrian social security number. A form field that validates its input as an Austrian social security number.
Belgium (``be``)
================
.. versionadded:: 1.3
.. class:: be.forms.BEPhoneNumberField
A form field that validates input as a Belgium phone number, with 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, 0x.xxx.xx.xx, 0xx.xx.xx.xx, 04xx.xx.xx.xx,
0xxxxxxxx or 04xxxxxxxx.
.. class:: be.forms.BEPostalCodeField
A form field that validates input as a Belgium postal code, in the range
and format 1XXX-9XXX.
.. class:: be.forms.BEProvinceSelect
A ``Select`` widget that uses a list of Belgium provinces as its
choices.
.. class:: be.forms.BERegionSelect
A ``Select`` widget that uses a list of Belgium regions as its
choices.
Brazil (``br``) Brazil (``br``)
=============== ===============

View File

@ -0,0 +1,94 @@
from django.test import TestCase
from django.forms import *
from django.contrib.localflavor.be.forms import (BEPostalCodeField,
BEPhoneNumberField, BERegionSelect, BEProvinceSelect)
class BETests(TestCase):
"""
Test case to validate BE localflavor
"""
def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs):
self.assertRaises(error, callable, *args, **kwargs)
try:
callable(*args, **kwargs)
except error, e:
self.assertEqual(message, str(e))
def test_postal_code_field(self):
f = BEPostalCodeField()
self.assertEqual(u'1451', f.clean('1451'))
self.assertEqual(u'2540', f.clean('2540'))
err_message = "[u'Enter a valid postal code in the range and format 1XXX - 9XXX.']"
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '0287')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '14309')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '873')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '35 74')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '859A')
err_message = "[u'This field is required.']"
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '')
f = BEPostalCodeField(required=False)
self.assertEqual(u'1451', f.clean('1451'))
self.assertEqual(u'2540', f.clean('2540'))
self.assertEqual(u'', f.clean(''))
err_message = "[u'Enter a valid postal code in the range and format 1XXX - 9XXX.']"
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '0287')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '14309')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '873')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '35 74')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '859A')
def test_phone_number_field(self):
f = BEPhoneNumberField()
self.assertEqual(u'01 234 56 78', f.clean('01 234 56 78'))
self.assertEqual(u'01/234.56.78', f.clean('01/234.56.78'))
self.assertEqual(u'01.234.56.78', f.clean('01.234.56.78'))
self.assertEqual(u'012 34 56 78', f.clean('012 34 56 78'))
self.assertEqual(u'012/34.56.78', f.clean('012/34.56.78'))
self.assertEqual(u'012.34.56.78', f.clean('012.34.56.78'))
self.assertEqual(u'0412 34 56 78', f.clean('0412 34 56 78'))
self.assertEqual(u'0412/34.56.78', f.clean('0412/34.56.78'))
self.assertEqual(u'0412.34.56.78', f.clean('0412.34.56.78'))
self.assertEqual(u'012345678', f.clean('012345678'))
self.assertEqual(u'0412345678', f.clean('0412345678'))
err_message = "[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, 0x.xxx.xx.xx, 0xx.xx.xx.xx, 04xx.xx.xx.xx.']"
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '01234567')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '12/345.67.89')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '012/345.678.90')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '012/34.56.789')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '0123/45.67.89')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '012/345 678 90')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '012/34 56 789')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '012.34 56 789')
err_message = "[u'This field is required.']"
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '')
f = BEPhoneNumberField(required=False)
self.assertEqual(u'01 234 56 78', f.clean('01 234 56 78'))
self.assertEqual(u'01/234.56.78', f.clean('01/234.56.78'))
self.assertEqual(u'01.234.56.78', f.clean('01.234.56.78'))
self.assertEqual(u'012 34 56 78', f.clean('012 34 56 78'))
self.assertEqual(u'012/34.56.78', f.clean('012/34.56.78'))
self.assertEqual(u'012.34.56.78', f.clean('012.34.56.78'))
self.assertEqual(u'0412 34 56 78', f.clean('0412 34 56 78'))
self.assertEqual(u'0412/34.56.78', f.clean('0412/34.56.78'))
self.assertEqual(u'0412.34.56.78', f.clean('0412.34.56.78'))
self.assertEqual(u'012345678', f.clean('012345678'))
self.assertEqual(u'0412345678', f.clean('0412345678'))
self.assertEqual(u'', f.clean(''))
err_message = "[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, 0x.xxx.xx.xx, 0xx.xx.xx.xx, 04xx.xx.xx.xx.']"
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '01234567')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '12/345.67.89')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '012/345.678.90')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '012/34.56.789')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '0123/45.67.89')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '012/345 678 90')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '012/34 56 789')
self.assertRaisesErrorWithMessage(ValidationError, err_message, f.clean, '012.34 56 789')
def test_phone_number_field(self):
w = BERegionSelect()
self.assertEqual(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>', w.render('regions', 'VLG'))
def test_phone_number_field(self):
w = BEProvinceSelect()
self.assertEqual(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>', w.render('provinces', 'WLG'))

View File

@ -40,6 +40,7 @@ from media import media_tests
from fields import FieldsTests from fields import FieldsTests
from validators import TestFieldWithValidators from validators import TestFieldWithValidators
from widgets import WidgetTests, ClearableFileInputTests from widgets import WidgetTests, ClearableFileInputTests
from localflavor.be import BETests
from input_formats import * from input_formats import *