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:
parent
f2d0ae93f8
commit
3825bb2350
1
AUTHORS
1
AUTHORS
|
@ -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>
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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'),
|
||||||
|
)
|
|
@ -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.
|
||||||
|
|
|
@ -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.']
|
||||||
|
"""
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue