/django/contrib/localflavor/uy/forms.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