PageRenderTime 152ms CodeModel.GetById 80ms app.highlight 4ms RepoModel.GetById 67ms app.codeStats 0ms

/django/contrib/localflavor/uy/forms.py

https://code.google.com/p/mango-py/
Python | 60 lines | 47 code | 5 blank | 8 comment | 0 complexity | 6c5b0b1c3f897666196c4bd4968fdcba MD5 | raw file
 1# -*- coding: utf-8 -*-
 2"""
 3UY-specific form helpers.
 4"""
 5import re
 6
 7from django.core.validators import EMPTY_VALUES
 8from django.forms.fields import Select, RegexField
 9from django.forms import ValidationError
10from django.utils.translation import ugettext_lazy as _
11from django.contrib.localflavor.uy.util import get_validation_digit
12
13
14class UYDepartamentSelect(Select):
15    """
16    A Select widget that uses a list of Uruguayan departaments as its choices.
17    """
18    def __init__(self, attrs=None):
19        from uy_departaments import DEPARTAMENT_CHOICES
20        super(UYDepartamentSelect, self).__init__(attrs, choices=DEPARTAMENT_CHOICES)
21
22
23class UYCIField(RegexField):
24    """
25    A field that validates Uruguayan 'Cedula de identidad' (CI) numbers.
26    """
27    default_error_messages = {
28        'invalid': _("Enter a valid CI number in X.XXX.XXX-X,"
29                     "XXXXXXX-X or XXXXXXXX format."),
30        'invalid_validation_digit': _("Enter a valid CI number."),
31    }
32
33    def __init__(self, *args, **kwargs):
34        super(UYCIField, self).__init__(r'(?P<num>(\d{6,7}|(\d\.)?\d{3}\.\d{3}))-?(?P<val>\d)',
35                                        *args, **kwargs)
36
37    def clean(self, value):
38        """
39        Validates format and validation digit.
40
41        The official format is [X.]XXX.XXX-X but usually dots and/or slash are
42        omitted so, when validating, those characters are ignored if found in
43        the correct place. The three typically used formats are supported:
44        [X]XXXXXXX, [X]XXXXXX-X and [X.]XXX.XXX-X.
45        """
46
47        value = super(UYCIField, self).clean(value)
48        if value in EMPTY_VALUES:
49            return u''
50        match = self.regex.match(value)
51        if not match:
52            raise ValidationError(self.error_messages['invalid'])
53
54        number = int(match.group('num').replace('.', ''))
55        validation_digit = int(match.group('val'))
56
57        if not validation_digit == get_validation_digit(number):
58            raise ValidationError(self.error_messages['invalid_validation_digit'])
59
60        return value