Fixed #10736 - Added Uruguayan (uy) localflavor. Thanks to Gonzalo Saavedra for providing the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12041 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2010-01-01 21:31:47 +00:00
parent f2d0ae93f8
commit 3825bb2350
8 changed files with 158 additions and 0 deletions

View File

@ -383,6 +383,7 @@ answer newbie questions, and generally made Django that much better:
Rozza <ross.lawley@gmail.com> Rozza <ross.lawley@gmail.com>
Oliver Rutherfurd <http://rutherfurd.net/> Oliver Rutherfurd <http://rutherfurd.net/>
ryankanno ryankanno
Gonzalo Saavedra <gonzalosaavedra@gmail.com>
Manuel Saelices <msaelices@yaco.es> Manuel Saelices <msaelices@yaco.es>
Ivan Sagalaev (Maniac) <http://www.softwaremaniacs.org/> Ivan Sagalaev (Maniac) <http://www.softwaremaniacs.org/>
Vinay Sajip <vinay_sajip@yahoo.co.uk> Vinay Sajip <vinay_sajip@yahoo.co.uk>

View File

@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
"""
UY-specific form helpers.
"""
import re
from django.forms.fields import Select, RegexField, EMPTY_VALUES
from django.forms import ValidationError
from django.utils.translation import ugettext_lazy as _
from django.contrib.localflavor.uy.util import get_validation_digit
class UYDepartamentSelect(Select):
"""
A Select widget that uses a list of Uruguayan departaments as its choices.
"""
def __init__(self, attrs=None):
from uy_departaments import DEPARTAMENT_CHOICES
super(UYDepartamentSelect, self).__init__(attrs, choices=DEPARTAMENT_CHOICES)
class UYCIField(RegexField):
"""
A field that validates Uruguayan 'Cedula de identidad' (CI) numbers.
"""
default_error_messages = {
'invalid': _("Enter a valid CI number in X.XXX.XXX-X,"
"XXXXXXX-X or XXXXXXXX format."),
'invalid_validation_digit': _("Enter a valid CI number."),
}
def __init__(self, *args, **kwargs):
super(UYCIField, self).__init__(r'(?P<num>(\d{6,7}|(\d\.)?\d{3}\.\d{3}))-?(?P<val>\d)',
*args, **kwargs)
def clean(self, value):
"""
Validates format and validation digit.
The official format is [X.]XXX.XXX-X but usually dots and/or slash are
omitted so, when validating, those characters are ignored if found in
the correct place. The three typically used formats are supported:
[X]XXXXXXX, [X]XXXXXX-X and [X.]XXX.XXX-X.
"""
value = super(UYCIField, self).clean(value)
if value in EMPTY_VALUES:
return u''
match = self.regex.match(value)
if not match:
raise ValidationError(self.error_messages['invalid'])
number = int(match.group('num').replace('.', ''))
validation_digit = int(match.group('val'))
if not validation_digit == get_validation_digit(number):
raise ValidationError(self.error_messages['invalid_validation_digit'])
return value

View File

@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
def get_validation_digit(number):
""" Calculates the validation digit for the given number. """
sum = 0
dvs = [4, 3, 6, 7, 8, 9, 2]
number = str(number)
for i in range(0, len(number)):
sum = (int(number[-1 - i]) * dvs[i] + sum) % 10
return (10-sum) % 10

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
"""A list of Urguayan departaments as `choices` in a formfield."""
DEPARTAMENT_CHOICES = (
('G', u'Artigas'),
('A', u'Canelones'),
('E', u'Cerro Largo'),
('L', u'Colonia'),
('Q', u'Durazno'),
('N', u'Flores'),
('O', u'Florida'),
('P', u'Lavalleja'),
('B', u'Maldonado'),
('S', u'Montevideo'),
('I', u'Paysandú'),
('J', u'Río Negro'),
('F', u'Rivera'),
('C', u'Rocha'),
('H', u'Salto'),
('M', u'San José'),
('K', u'Soriano'),
('R', u'Tacuarembó'),
('D', u'Treinta y Tres'),
)

View File

@ -65,6 +65,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are:
* Switzerland_ * Switzerland_
* `United Kingdom`_ * `United Kingdom`_
* `United States of America`_ * `United States of America`_
* Uruguay_
The ``django.contrib.localflavor`` package also includes a ``generic`` subpackage, The ``django.contrib.localflavor`` package also includes a ``generic`` subpackage,
containing useful code that is not specific to one particular country or culture. containing useful code that is not specific to one particular country or culture.
@ -106,6 +107,7 @@ Here's an example of how to use them::
.. _Switzerland: `Switzerland (ch)`_ .. _Switzerland: `Switzerland (ch)`_
.. _United Kingdom: `United Kingdom (uk)`_ .. _United Kingdom: `United Kingdom (uk)`_
.. _United States of America: `United States of America (us)`_ .. _United States of America: `United States of America (us)`_
.. _Uruguay: `Uruguay (uy)`_
Adding flavors Adding flavors
============== ==============
@ -738,3 +740,15 @@ United States of America (``us``)
A model field that forms represent as a ``forms.USStateField`` field and A model field that forms represent as a ``forms.USStateField`` field and
stores the two-letter U.S. state abbreviation in the database. stores the two-letter U.S. state abbreviation in the database.
Uruguay (``uy``)
================
.. class:: uy.forms.UYCIField
A field that validates Uruguayan 'Cedula de identidad' (CI) numbers.
.. class:: uy.forms.UYDepartamentSelect
A ``Select`` widget that uses a list of Uruguayan departaments as its
choices.

View File

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Tests for the contrib/localflavor/ UY form fields.
tests = r"""
# UYDepartamentSelect #########################################################
>>> from django.contrib.localflavor.uy.forms import UYDepartamentSelect
>>> f = UYDepartamentSelect()
>>> f.render('departamentos', 'S')
u'<select name="departamentos">\n<option value="G">Artigas</option>\n<option value="A">Canelones</option>\n<option value="E">Cerro Largo</option>\n<option value="L">Colonia</option>\n<option value="Q">Durazno</option>\n<option value="N">Flores</option>\n<option value="O">Florida</option>\n<option value="P">Lavalleja</option>\n<option value="B">Maldonado</option>\n<option value="S" selected="selected">Montevideo</option>\n<option value="I">Paysand\xfa</option>\n<option value="J">R\xedo Negro</option>\n<option value="F">Rivera</option>\n<option value="C">Rocha</option>\n<option value="H">Salto</option>\n<option value="M">San Jos\xe9</option>\n<option value="K">Soriano</option>\n<option value="R">Tacuaremb\xf3</option>\n<option value="D">Treinta y Tres</option>\n</select>'
# UYCIField ###################################################################
>>> from django.contrib.localflavor.uy.util import get_validation_digit
>>> get_validation_digit(409805) == 3
True
>>> get_validation_digit(1005411) == 2
True
>>> from django.contrib.localflavor.uy.forms import UYCIField
>>> f = UYCIField()
>>> f.clean('4098053')
u'4098053'
>>> f.clean('409805-3')
u'409805-3'
>>> f.clean('409.805-3')
u'409.805-3'
>>> f.clean('10054112')
u'10054112'
>>> f.clean('1005411-2')
u'1005411-2'
>>> f.clean('1.005.411-2')
u'1.005.411-2'
>>> f.clean('foo')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid CI number in X.XXX.XXX-X,XXXXXXX-X or XXXXXXXX format.']
>>> f.clean('409805-2')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid CI number.']
>>> f.clean('1.005.411-5')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid CI number.']
"""

View File

@ -25,6 +25,7 @@ from localflavor.se import tests as localflavor_se_tests
from localflavor.sk import tests as localflavor_sk_tests from localflavor.sk import tests as localflavor_sk_tests
from localflavor.uk import tests as localflavor_uk_tests from localflavor.uk import tests as localflavor_uk_tests
from localflavor.us import tests as localflavor_us_tests from localflavor.us import tests as localflavor_us_tests
from localflavor.uy import tests as localflavor_uy_tests
from localflavor.za import tests as localflavor_za_tests from localflavor.za import tests as localflavor_za_tests
from regressions import tests as regression_tests from regressions import tests as regression_tests
from util import tests as util_tests from util import tests as util_tests
@ -61,6 +62,7 @@ __test__ = {
'localflavor_sk_tests': localflavor_sk_tests, 'localflavor_sk_tests': localflavor_sk_tests,
'localflavor_uk_tests': localflavor_uk_tests, 'localflavor_uk_tests': localflavor_uk_tests,
'localflavor_us_tests': localflavor_us_tests, 'localflavor_us_tests': localflavor_us_tests,
'localflavor_uy_tests': localflavor_uy_tests,
'localflavor_za_tests': localflavor_za_tests, 'localflavor_za_tests': localflavor_za_tests,
'regression_tests': regression_tests, 'regression_tests': regression_tests,
'formset_tests': formset_tests, 'formset_tests': formset_tests,