Ticket #3946: ch-localflavor2.diff
File ch-localflavor2.diff, 8.7 KB (added by , 18 years ago) |
---|
-
django/contrib/localflavor/ch/ch_states.py
1 # -*- coding: utf-8 -* 2 from django.utils.translation import gettext_lazy as _ 3 4 STATE_CHOICES = ( 5 ('AG', _('Aargau')), 6 ('AI', _('Appenzell Innerrhoden')), 7 ('AR', _('Appenzell Ausserrhoden')), 8 ('BS', _('Basel-Stadt')), 9 ('BL', _('Basel-Land')), 10 ('BE', _('Berne')), 11 ('FR', _('Fribourg')), 12 ('GE', _('Geneva')), 13 ('GL', _('Glarus')), 14 ('GR', _('Graubuenden')), 15 ('JU', _('Jura')), 16 ('LU', _('Lucerne')), 17 ('NE', _('Neuchatel')), 18 ('NW', _('Nidwalden')), 19 ('OW', _('Obwalden')), 20 ('SH', _('Schaffhausen')), 21 ('SZ', _('Schwyz')), 22 ('SO', _('Solothurn')), 23 ('SG', _('St. Gallen')), 24 ('TG', _('Thurgau')), 25 ('TI', _('Ticino')), 26 ('UR', _('Uri')), 27 ('VS', _('Valais')), 28 ('VD', _('Vaud')), 29 ('ZG', _('Zug')), 30 ('ZH', _('Zurich')) 31 ) -
django/contrib/localflavor/ch/forms.py
1 """ 2 Swiss-specific Form helpers 3 """ 4 5 from django.newforms import ValidationError 6 from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES 7 from django.utils.encoding import smart_unicode 8 from django.utils.translation import gettext 9 import re 10 11 id_re = re.compile(r"^(?P<idnumber>\w{8})(?P<pos9>(\d{1}|<))(?P<checksum>\d{1})$") 12 phone_digits_re = re.compile(r'^0([1-9]{1})\d{8}$') 13 14 class CHZipCodeField(RegexField): 15 def __init__(self, *args, **kwargs): 16 super(CHZipCodeField, self).__init__(r'^\d{4}$', 17 max_length=None, min_length=None, 18 error_message=gettext('Enter a zip code in the format XXXX.'), 19 *args, **kwargs) 20 21 class CHPhoneNumberField(Field): 22 """ 23 Validate local Swiss phone number (not international ones) 24 The correct format is '0XX XXX XX XX'. 25 '0XX.XXX.XX.XX' and '0XXXXXXXXX' validate but are corrected to 26 '0XX XXX XX XX'. 27 """ 28 def clean(self, value): 29 super(CHPhoneNumberField, self).clean(value) 30 if value in EMPTY_VALUES: 31 return u'' 32 value = re.sub('(\.|\s|/|-)', '', smart_unicode(value)) 33 m = phone_digits_re.search(value) 34 if m: 35 return u'%s %s %s %s' % (value[0:3], value[3:6], value[6:8], value[8:10]) 36 raise ValidationError('Phone numbers must be in 0XX XXX XX XX format.') 37 38 class CHStateSelect(Select): 39 """ 40 A Select widget that uses a list of CH states as its choices. 41 """ 42 def __init__(self, attrs=None): 43 from ch_states import STATE_CHOICES # relative import 44 super(CHStateSelect, self).__init__(attrs, choices=STATE_CHOICES) 45 46 class CHIdentityCardNumberField(Field): 47 """ 48 A Swiss identity card number. 49 50 Checks the following rules to determine whether the number is valid: 51 52 * Conforms to the X1234567<0 or 1234567890 format. 53 * Included checksums match calculated checksums 54 55 Algorithm is documented at http://adi.kousz.ch/artikel/IDCHE.htm 56 """ 57 58 def has_valid_checksum(self, number): 59 given_number, given_checksum = number[:-1], number[-1] 60 new_number = given_number 61 calculated_checksum = 0 62 fragment = "" 63 parameter = 7 64 65 first = str(number[:1]) 66 if first.isalpha(): 67 num = ord(first.upper()) - 65 68 if num < 0 or num > 8: 69 return False 70 new_number = str(num) + new_number[1:] 71 new_number = new_number[:8] + '0' 72 73 if not new_number.isdigit(): 74 return False 75 76 for i in range(len(new_number)): 77 fragment = int(new_number[i])*parameter 78 calculated_checksum += fragment 79 80 if parameter == 1: 81 parameter = 7 82 elif parameter == 3: 83 parameter = 1 84 elif parameter ==7: 85 parameter = 3 86 87 return str(calculated_checksum)[-1] == given_checksum 88 89 def clean(self, value): 90 super(CHIdentityCardNumberField, self).clean(value) 91 error_msg = gettext('Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format') 92 if value in EMPTY_VALUES: 93 return u'' 94 95 match = re.match(id_re, value) 96 if not match: 97 raise ValidationError(error_msg) 98 99 idnumber, pos9, checksum = match.groupdict()['idnumber'], match.groupdict()['pos9'], match.groupdict()['checksum'] 100 101 if idnumber == '00000000' or \ 102 idnumber == 'A0000000': 103 raise ValidationError(error_msg) 104 105 all_digits = "%s%s%s" % (idnumber, pos9, checksum) 106 if not self.has_valid_checksum(all_digits): 107 raise ValidationError(error_msg) 108 109 return u'%s%s%s' % (idnumber, pos9, checksum) -
tests/regressiontests/forms/localflavor.py
882 882 Traceback (most recent call last): 883 883 ... 884 884 ValidationError: [u'Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format.'] 885 <<<<<<< .mine 885 886 887 # CHZipCodeField ############################################################ 888 889 >>> from django.contrib.localflavor.ch.forms import CHZipCodeField 890 >>> f = CHZipCodeField() 891 >>> f.clean('800x') 892 Traceback (most recent call last): 893 ... 894 ValidationError: [u'Enter a zip code in the format XXXX.'] 895 >>> f.clean('80 00') 896 Traceback (most recent call last): 897 ... 898 ValidationError: [u'Enter a zip code in the format XXXX.'] 899 >>> f.clean('8000') 900 u'8000' 901 902 # CHPhoneNumberField ######################################################## 903 904 >>> from django.contrib.localflavor.ch.forms import CHPhoneNumberField 905 >>> f = CHPhoneNumberField() 906 >>> f.clean('01234567890') 907 Traceback (most recent call last): 908 ... 909 ValidationError: [u'Phone numbers must be in 0XX XXX XX XX format.'] 910 >>> f.clean('1234567890') 911 Traceback (most recent call last): 912 ... 913 ValidationError: [u'Phone numbers must be in 0XX XXX XX XX format.'] 914 >>> f.clean('0123456789') 915 u'012 345 67 89' 916 917 # CHIdentityCardNumberField ################################################# 918 919 >>> from django.contrib.localflavor.ch.forms import CHIdentityCardNumberField 920 >>> f = CHIdentityCardNumberField() 921 >>> f.clean('C1234567<0') 922 u'C1234567<0' 923 >>> f.clean('C1234567<1') 924 Traceback (most recent call last): 925 ... 926 ValidationError: [u'Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format'] 927 >>> f.clean('2123456700') 928 u'2123456700' 929 >>> f.clean('2123456701') 930 Traceback (most recent call last): 931 ... 932 ValidationError: [u'Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format'] 933 934 # CHStateSelect ############################################################# 935 936 >>> from django.contrib.localflavor.ch.forms import CHStateSelect 937 >>> w = CHStateSelect() 938 >>> w.render('state', 'AG') 939 u'<select name="state">\n<option value="AG" selected="selected">Aargau</option>\n<option value="AI">Appenzell Innerrhoden</option>\n<option value="AR">Appenzell Ausserrhoden</option>\n<option value="BS">Basel-Stadt</option>\n<option value="BL">Basel-Land</option>\n<option value="BE">Berne</option>\n<option value="FR">Fribourg</option>\n<option value="GE">Geneva</option>\n<option value="GL">Glarus</option>\n<option value="GR">Graubuenden</option>\n<option value="JU">Jura</option>\n<option value="LU">Lucerne</option>\n<option value="NE">Neuchatel</option>\n<option value="NW">Nidwalden</option>\n<option value="OW">Obwalden</option>\n<option value="SH">Schaffhausen</option>\n<option value="SZ">Schwyz</option>\n<option value="SO">Solothurn</option>\n<option value="SG">St. Gallen</option>\n<option value="TG">Thurgau</option>\n<option value="TI">Ticino</option>\n<option value="UR">Uri</option>\n<option value="VS">Valais</option>\n<option value="VD">Vaud</option>\n<option value="ZG">Zug</option>\n<option value="ZH">Zurich</option>\n</select>' 940 ======= 941 886 942 ## AUPostCodeField ########################################################## 887 943 888 944 A field that accepts a four digit Australian post code. … … 1012 1068 <option value="VIC">Victoria</option> 1013 1069 <option value="WA">Western Australia</option> 1014 1070 </select> 1071 >>>>>>> .r4955 1015 1072 """