Ticket #11517: patch_clpatentefield-16716.diff
File patch_clpatentefield-16716.diff, 6.0 KB (added by , 13 years ago) |
---|
-
django/contrib/localflavor/cl/forms.py
4 4 5 5 from django.core.validators import EMPTY_VALUES 6 6 from django.forms import ValidationError 7 from django.forms.fields import RegexField, Select 7 from django.forms.fields import RegexField, Select, CharField 8 8 from django.utils.translation import ugettext_lazy as _ 9 9 from django.utils.encoding import smart_unicode 10 10 11 OLD_CAR_PLATE_STYLE = 0 12 NEW_CAR_PLATE_STYLE = 1 11 13 14 12 15 class CLRegionSelect(Select): 13 16 """ 14 17 A Select widget that uses a list of Chilean Regions (Regiones) … … 93 96 code = code[:new_dot] + '.' + code[new_dot:] 94 97 return u'%s-%s' % (code, verifier) 95 98 99 100 class CLPatenteField(CharField): 101 """ 102 Chilean "Patente", Placa Patente Field, support old LL-NNNN and new LLLL-NN 103 type, where L in new can't be vowel or m,n and q. 104 """ 105 default_error_messages = { 106 'invalid': _("Enter a valid Chilean Car Plate."), 107 } 108 109 def __init__(self, *args, **kwargs): 110 kwargs['max_length'] = 7 111 kwargs['min_length'] = 6 112 if not kwargs.has_key('label'): 113 kwargs['label'] = _("Car plate") 114 if not kwargs.has_key('help_text'): 115 kwargs['help_text'] = _("Chilean car plate as LL-NNNN or LLLL-NN") 116 117 super(CLPatenteField, self).__init__(*args, **kwargs) 118 119 def clean(self, value): 120 """ 121 Check and clean the field for length and type. 122 """ 123 super(CLPatenteField, self).clean(value) 124 125 if value in EMPTY_VALUES: 126 return u'' 127 128 value = smart_unicode(value.lower()) 129 value_length = len(value) 130 131 if self.max_length is not None and value_length > self.max_length: 132 raise ValidationError(self.error_messages['max_length'] % {'max': self.max_length, 'length': value_length}) 133 if self.min_length is not None and value_length < self.min_length: 134 raise ValidationError(self.error_messages['min_length'] % {'min': self.min_length, 'length': value_length}) 135 136 value = self._canonify(value) 137 _type = self._algorithm(value) 138 139 if _type not in (OLD_CAR_PLATE_STYLE, NEW_CAR_PLATE_STYLE): 140 raise ValidationError(self.error_messages['invalid']) 141 142 return self._format(value.upper(), _type) 143 144 def _algorithm(self, value): 145 """ 146 Takes Car Plate in canonical form and verify if it is valid. 147 Returns the type or None if it is not valid. 148 """ 149 import re 150 # Old card plate patern 151 op = '^[a-z]{2,2}\d{4,4}$' 152 op = re.compile(op) 153 # New card plate patern 154 np = '^[bcdfghjklprstvwxyz]{4,4}\d{2,2}$' 155 np = re.compile(np) 156 if re.search(op, value): 157 return OLD_CAR_PLATE_STYLE 158 elif re.search(np, value): 159 return NEW_CAR_PLATE_STYLE 160 else: 161 return None 162 163 def _canonify(self, patente): 164 """ 165 Turns the Car Plate into one normalized format. 166 """ 167 return patente.replace(' ', '').replace('-', '') 168 169 def _format(self, value, _type): 170 """ 171 Formats the Car Plate from canonical form to the common string 172 representation. LL-DDDD or LLLL-DD 173 """ 174 if _type == OLD_CAR_PLATE_STYLE: 175 return u'-'.join((value[:2], value[2:])) 176 if _type == NEW_CAR_PLATE_STYLE: 177 return u'-'.join((value[:4], value[4:])) -
tests/regressiontests/localflavor/cl/tests.py
1 from django.contrib.localflavor.cl.forms import CLRutField, CLRegionSelect 1 from django.contrib.localflavor.cl.forms import CLRutField, CLRegionSelect, CLPatenteField 2 2 3 from django.core.validators import MinLengthValidator, MaxLengthValidator 4 5 3 6 from django.test import SimpleTestCase 4 7 5 8 … … 54 57 self.assertFieldOutput(CLRutField, 55 58 {}, invalid, field_kwargs={"strict": True} 56 59 ) 60 61 def test_CLPatente(self): 62 """ Tests that the field validates input""" 63 invalid_min_length_data = 'p' 64 invalid_max_length_data = 'pcpcpcpc' 65 66 error_invalid = [CLPatenteField().default_error_messages['invalid']] 67 68 error_min_length = [MinLengthValidator.message % {'limit_value': CLPatenteField().min_length, 'show_value' :len(invalid_min_length_data)}] 69 error_max_length = [MaxLengthValidator.message % {'limit_value': CLPatenteField().max_length, 'show_value' :len(invalid_max_length_data)}] 70 71 valid = { 72 # Valid new style 73 'rrwr56': 'RRWR-56', 74 'rrwr-56': 'RRWR-56', 75 # Valid old style 76 'aa6056': 'AA-6056', 77 'aa-6056':'AA-6056' 78 } 79 invalid = { 80 invalid_min_length_data: error_min_length, 81 invalid_max_length_data: error_max_length, 82 'ppppcpc': error_invalid, 83 'cpcpcp': error_invalid, 84 'cpcpc0': error_invalid, 85 'cpc606': error_invalid, 86 'c60606': error_invalid, 87 '606060': error_invalid, 88 # Can't contain 'm' 89 'mttt12': error_invalid, 90 # Can't contain 'n' 91 'nttt34': error_invalid, 92 # Can't contain 'q' 93 'qttt56': error_invalid, 94 # Can't contain vowel 95 # 'a' 96 'attt67': error_invalid, 97 # 'e' 98 'ettt67': error_invalid, 99 # 'i' 100 'ittt89': error_invalid, 101 # 'o' 102 'ottt01': error_invalid, 103 # 'u' 104 'uttt23': error_invalid 105 } 106 107 self.assertFieldOutput(CLPatenteField, valid, invalid)