From 63662ff924ccea2d19486f0b7d525c3d2341c12c Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Fri, 1 Jan 2010 21:35:26 +0000 Subject: [PATCH] Fixed #8735 - Added Portuguese (pt) local flavor. Thanks Alcides Fonseca for the patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@12047 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 1 + django/contrib/localflavor/pt/__init__.py | 0 django/contrib/localflavor/pt/forms.py | 47 ++++++++ docs/ref/contrib/localflavor.txt | 21 +++- tests/regressiontests/forms/localflavor/pt.py | 106 ++++++++++++++++++ tests/regressiontests/forms/tests.py | 2 + 6 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 django/contrib/localflavor/pt/__init__.py create mode 100644 django/contrib/localflavor/pt/forms.py create mode 100644 tests/regressiontests/forms/localflavor/pt.py diff --git a/AUTHORS b/AUTHORS index 066a07e213..9ca5753804 100644 --- a/AUTHORS +++ b/AUTHORS @@ -28,6 +28,7 @@ answer newbie questions, and generally made Django that much better: ajs alang@bright-green.com + Alcides Fonseca Andi Albrecht Marty Alchin Ahmad Alhashemi diff --git a/django/contrib/localflavor/pt/__init__.py b/django/contrib/localflavor/pt/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/django/contrib/localflavor/pt/forms.py b/django/contrib/localflavor/pt/forms.py new file mode 100644 index 0000000000..86833fc85f --- /dev/null +++ b/django/contrib/localflavor/pt/forms.py @@ -0,0 +1,47 @@ +""" +PT-specific Form helpers +""" + +from django.forms import ValidationError +from django.forms.fields import Field, RegexField, Select, EMPTY_VALUES +from django.utils.encoding import smart_unicode +from django.utils.translation import ugettext_lazy as _ +import re + +phone_digits_re = re.compile(r'^(\d{9}|(00|\+)\d*)$') + + +class PTZipCodeField(RegexField): + default_error_messages = { + 'invalid': _('Enter a zip code in the format XXXX-XXX.'), + } + + def __init__(self, *args, **kwargs): + super(PTZipCodeField, self).__init__(r'^(\d{4}-\d{3}|\d{7})$', + max_length=None, min_length=None, *args, **kwargs) + + def clean(self,value): + cleaned = super(PTZipCodeField, self).clean(value) + if len(cleaned) == 7: + return u'%s-%s' % (cleaned[:4],cleaned[4:]) + else: + return cleaned + +class PTPhoneNumberField(Field): + """ + Validate local Portuguese phone number (including international ones) + It should have 9 digits (may include spaces) or start by 00 or + (international) + """ + default_error_messages = { + 'invalid': _('Phone numbers must have 9 digits, or start by + or 00.'), + } + + def clean(self, value): + super(PTPhoneNumberField, self).clean(value) + if value in EMPTY_VALUES: + return u'' + value = re.sub('(\.|\s)', '', smart_unicode(value)) + m = phone_digits_re.search(value) + if m: + return u'%s' % value + raise ValidationError(self.error_messages['invalid']) diff --git a/docs/ref/contrib/localflavor.txt b/docs/ref/contrib/localflavor.txt index 81c6f2431b..1c58e2d5e8 100644 --- a/docs/ref/contrib/localflavor.txt +++ b/docs/ref/contrib/localflavor.txt @@ -60,6 +60,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are: * Norway_ * Peru_ * Poland_ + * Portugal_ * Romania_ * Slovakia_ * `South Africa`_ @@ -105,6 +106,7 @@ Here's an example of how to use them:: .. _Norway: `Norway (no)`_ .. _Peru: `Peru (pe)`_ .. _Poland: `Poland (pl)`_ +.. _Portugal: `Portugal (pt)`_ .. _Romania: `Romania (ro)`_ .. _Slovakia: `Slovakia (sk)`_ .. _South Africa: `South Africa (za)`_ @@ -498,17 +500,17 @@ Norway (``no``) Peru (``pe``) ============= -.. class:: pt.forms.PEDNIField +.. class:: pe.forms.PEDNIField A form field that validates input as a DNI (Peruvian national identity) number. -.. class:: pt.forms.PERUCField +.. class:: pe.forms.PERUCField A form field that validates input as an RUC (Registro Unico de Contribuyentes) number. Valid RUC numbers have 11 digits. -.. class:: pt.forms.PEDepartmentSelect +.. class:: pe.forms.PEDepartmentSelect A ``Select`` widget that uses a list of Peruvian Departments as its choices. @@ -552,6 +554,19 @@ Poland (``pl``) A ``Select`` widget that uses a list of Polish voivodeships (administrative provinces) as its choices. +Portugal (``pt``) +================= + +.. class:: pt.forms.PTZipCodeField + + A form field that validates input as a Portuguese zip code. + +.. class:: pt.forms.PTPhoneNumberField + + A form field that validates input as a Portuguese phone number. + Valid numbers have 9 digits (may include spaces) or start by 00 + or + (international). + Romania (``ro``) ================ diff --git a/tests/regressiontests/forms/localflavor/pt.py b/tests/regressiontests/forms/localflavor/pt.py new file mode 100644 index 0000000000..56d4d54c02 --- /dev/null +++ b/tests/regressiontests/forms/localflavor/pt.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +# Tests for the contrib/localflavor/ PT form fields. + +tests = r""" +# PTZipCodeField ############################################################# + +PTZipCodeField validates that the data is a valid PT zipcode. +>>> from django.contrib.localflavor.pt.forms import PTZipCodeField +>>> f = PTZipCodeField() +>>> f.clean('3030-034') +u'3030-034' +>>> f.clean('1003456') +u'1003-456' +>>> f.clean('2A200') +Traceback (most recent call last): +... +ValidationError: [u'Enter a zip code in the format XXXX-XXX.'] +>>> f.clean('980001') +Traceback (most recent call last): +... +ValidationError: [u'Enter a zip code in the format XXXX-XXX.'] +>>> f.clean(None) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] + +>>> f = PTZipCodeField(required=False) +>>> f.clean('3030-034') +u'3030-034' +>>> f.clean('1003456') +u'1003-456' +>>> f.clean('2A200') +Traceback (most recent call last): +... +ValidationError: [u'Enter a zip code in the format XXXX-XXX.'] +>>> f.clean('980001') +Traceback (most recent call last): +... +ValidationError: [u'Enter a zip code in the format XXXX-XXX.'] +>>> f.clean(None) +u'' +>>> f.clean('') +u'' + +# PTPhoneNumberField ########################################################## + +PTPhoneNumberField validates that the data is a valid Portuguese phone number. +It's normalized to XXXXXXXXX format or +X(X) for international numbers. Dots are valid too. +>>> from django.contrib.localflavor.pt.forms import PTPhoneNumberField +>>> f = PTPhoneNumberField() +>>> f.clean('917845189') +u'917845189' +>>> f.clean('91 784 5189') +u'917845189' +>>> f.clean('91 784 5189') +u'917845189' +>>> f.clean('+351 91 111') +u'+35191111' +>>> f.clean('00351873') +u'00351873' +>>> f.clean('91 784 51 8') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must have 9 digits, or start by + or 00.'] +>>> f.clean('091 456 987 1') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must have 9 digits, or start by + or 00.'] +>>> f.clean(None) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] + +>>> f = PTPhoneNumberField(required=False) +>>> f.clean('917845189') +u'917845189' +>>> f.clean('91 784 5189') +u'917845189' +>>> f.clean('91 784 5189') +u'917845189' +>>> f.clean('+351 91 111') +u'+35191111' +>>> f.clean('00351873') +u'00351873' +>>> f.clean('91 784 51 8') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must have 9 digits, or start by + or 00.'] +>>> f.clean('091 456 987 1') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must have 9 digits, or start by + or 00.'] +>>> f.clean(None) +u'' +>>> f.clean('') +u'' + +""" diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index 72dcad89c9..89140f04b1 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -23,6 +23,7 @@ from localflavor.jp import tests as localflavor_jp_tests from localflavor.kw import tests as localflavor_kw_tests from localflavor.nl import tests as localflavor_nl_tests from localflavor.pl import tests as localflavor_pl_tests +from localflavor.pt import tests as localflavor_pt_tests from localflavor.ro import tests as localflavor_ro_tests from localflavor.se import tests as localflavor_se_tests from localflavor.sk import tests as localflavor_sk_tests @@ -63,6 +64,7 @@ __test__ = { 'localflavor_kw_tests': localflavor_kw_tests, 'localflavor_nl_tests': localflavor_nl_tests, 'localflavor_pl_tests': localflavor_pl_tests, + 'localflavor_pt_tests': localflavor_pt_tests, 'localflavor_ro_tests': localflavor_ro_tests, 'localflavor_se_tests': localflavor_se_tests, 'localflavor_sk_tests': localflavor_sk_tests,