Ticket #8798: r17015-dephonenumberfield.diff
File r17015-dephonenumberfield.diff, 6.0 KB (added by , 13 years ago) |
---|
-
docs/ref/contrib/localflavor.txt
551 551 552 552 .. _Personalausweis: http://de.wikipedia.org/wiki/Personalausweis 553 553 554 .. class:: de.forms.DEPhoneNumberField 555 556 A form field that validates input as a German telephone 557 number. `Several formats`_ are accepted. The field value is 558 normalized to format 0301234567, which always includes the area 559 code with a leading zero and does not include the (optional) 560 country code. Extra spaces, hyphens, and parentheses in the phone 561 number are removed. 562 563 .. _Several formats: http://de.wikipedia.org/wiki/Rufnummer#Schreibweisen 564 554 565 .. class:: de.forms.DEZipCodeField 555 566 556 567 A form field that validates input as a German zip code. Valid codes -
tests/regressiontests/localflavor/de/tests.py
1 1 from django.contrib.localflavor.de.forms import (DEZipCodeField, DEStateSelect, 2 DEIdentityCardNumberField )2 DEIdentityCardNumberField, DEPhoneNumberField) 3 3 4 4 from django.test import SimpleTestCase 5 5 … … 47 47 '0434657485D-6407276-0508137-9': error_format, 48 48 } 49 49 self.assertFieldOutput(DEIdentityCardNumberField, valid, invalid) 50 51 def test_DEPhoneNumberField(self): 52 error_format = [u'Enter a valid German phone number in (030) 1234567 format.'] 53 valid = { 54 '+49 30 12345-67': '0301234567', 55 '+49 30 1234567': '0301234567', 56 '+49 (30) 1234567': '0301234567', 57 '+49-30-1234567': '0301234567', 58 '+49 (0)30 12345-67': '0301234567', 59 '030 12345-67': '0301234567', 60 '(030) 12345 67': '0301234567', 61 '0900 5 123456': '09005123456', 62 '(0)30 12345 67': '0301234567', 63 '(0)301234567': '0301234567', 64 '0049 (30) 1234567': '0301234567', 65 '0049301234567': '0301234567', 66 '+49301234567': '0301234567', 67 '0301234567': '0301234567', 68 } 69 invalid = { 70 # Unexpected country code: 71 '+1 30 12345-67': error_format, 72 # Invalid area code: 73 '(0030) 12345-67': error_format, 74 # Ambiguous area code: 75 '30 12345-67': error_format, 76 # Ambiguous spacing: 77 '(0) 301234567': error_format, 78 # Leading zero in number: 79 '(030) 012345-67': error_format, 80 '030-012345-67': error_format, 81 '(0)30 012345-67': error_format, 82 # Too many spaces/hyphens. 83 '+49 (0)30 12345--67': error_format, 84 ' (0)30 12345-67': error_format, 85 '(0)30 12345-67 ': error_format, 86 '-030 1234567': error_format, 87 '030 1234567': error_format, 88 } 89 self.assertFieldOutput(DEPhoneNumberField, valid, invalid) 90 valid = {} 91 invalid = { 92 '+1 30 12345-67': [u'Just enter something!'], 93 } 94 kwargs = {'error_messages': {'invalid': u'Just enter something!'}} 95 self.assertFieldOutput(DEPhoneNumberField, valid, invalid, field_kwargs=kwargs) -
django/contrib/localflavor/de/forms.py
66 66 return str(calculated_checksum)[-1] == given_checksum 67 67 68 68 def clean(self, value): 69 super(DEIdentityCardNumberField, self).clean(value)69 value = super(DEIdentityCardNumberField, self).clean(value) 70 70 if value in EMPTY_VALUES: 71 71 return u'' 72 72 match = re.match(id_re, value) … … 86 86 raise ValidationError(self.error_messages['invalid']) 87 87 88 88 return u'%s%s-%s-%s-%s' % (residence, origin, birthday, validity, checksum) 89 90 class DEPhoneNumberField(Field): 91 """ 92 A German phone number. 93 94 The phone number may be in one of the following formats: 95 96 * DIN 5008: +49 30 12345-67, or 030 12345-67 97 * E.123: +49 30 1234567, or (030) 12345 67 98 * Microsoft: +49 (30) 1234567 99 * RFC 3966 (URI): +49-30-1234567 100 * Informal notation: +49 (0)30 12345-67 101 102 As an alternative to the optional +49, a prefix of 0049 is also 103 acceptable. The country code (if given) is stripped. The leading 104 zero in the area code is stated explicitly if omitted. The phone 105 numbers above all resolve to the normalized form 0301234567. 106 107 For more details, see: 108 http://de.wikipedia.org/wiki/Rufnummer#Schreibweisen 109 """ 110 default_error_messages = { 111 'invalid': _(u'Enter a valid German phone number in (030) 1234567 format.'), 112 } 113 phone_regex = re.compile(r'^(?P<country>(\+|00)49[\s-]?)?(?P<phone>(\(0?[1-9]\d{1,3}\)|0?[1-9]\d{1,3}|\(0\)[1-9]\d{1,3})([\s-]?[1-9]\d*)([\s-]?\d+)*)$') 114 strip_regex = re.compile(r'[()\s-]') 115 116 def clean(self, value): 117 value = super(DEPhoneNumberField, self).clean(value) 118 if value in EMPTY_VALUES: 119 return u'' 120 match = self.phone_regex.match(value) 121 if not match: 122 raise ValidationError(self.error_messages['invalid']) 123 phone = self.strip_regex.sub('', match.group('phone')) 124 # At this point, phone has at least two characters. 125 if phone[0] != u'0': 126 if not match.group('country'): 127 # When no country code was given, we expect a leading 128 # 0 in the area code to avoid any ambiguities between 129 # numbers with and without area code. 130 raise ValidationError(self.error_messages['invalid']) 131 phone = u'0' + phone 132 return phone