From 0fe8c20a2830c62881947e8f017963c0c2142287 Mon Sep 17 00:00:00 2001 From: Karen Tracey Date: Sun, 13 Dec 2009 17:01:22 +0000 Subject: [PATCH] Fixed #12146: Corrected Canadian postal code validation. Thanks paulschreiber and Mark Lavin. git-svn-id: http://code.djangoproject.com/svn/django/trunk@11844 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/localflavor/ca/forms.py | 11 ++++- tests/regressiontests/forms/localflavor/ca.py | 44 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/django/contrib/localflavor/ca/forms.py b/django/contrib/localflavor/ca/forms.py index 327d938373..542ff40670 100644 --- a/django/contrib/localflavor/ca/forms.py +++ b/django/contrib/localflavor/ca/forms.py @@ -12,13 +12,20 @@ phone_digits_re = re.compile(r'^(?:1-?)?(\d{3})[-\.]?(\d{3})[-\.]?(\d{4})$') sin_re = re.compile(r"^(\d{3})-(\d{3})-(\d{3})$") class CAPostalCodeField(RegexField): - """Canadian postal code field.""" + """ + Canadian postal code field. + + Validates against known invalid characters: D, F, I, O, Q, U + Additionally the first character cannot be Z or W. + For more info see: + http://www.canadapost.ca/tools/pg/manual/PGaddress-e.asp#1402170 + """ default_error_messages = { 'invalid': _(u'Enter a postal code in the format XXX XXX.'), } def __init__(self, *args, **kwargs): - super(CAPostalCodeField, self).__init__(r'^[ABCEGHJKLMNPRSTVXYZ]\d[A-Z] \d[A-Z]\d$', + super(CAPostalCodeField, self).__init__(r'^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] \d[ABCEGHJKLMNPRSTVWXYZ]\d$', max_length=None, min_length=None, *args, **kwargs) class CAPhoneNumberField(Field): diff --git a/tests/regressiontests/forms/localflavor/ca.py b/tests/regressiontests/forms/localflavor/ca.py index 48171b0558..7f4b3ac89c 100644 --- a/tests/regressiontests/forms/localflavor/ca.py +++ b/tests/regressiontests/forms/localflavor/ca.py @@ -60,6 +60,50 @@ ValidationError: [u'Enter a postal code in the format XXX XXX.'] u'' >>> f.clean('') u'' +>>> f.clean('W2S 2H3') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('T2W 2H7') +u'T2W 2H7' +>>> f.clean('T2S 2W7') +u'T2S 2W7' +>>> f.clean('Z2S 2H3') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('T2Z 2H7') +u'T2Z 2H7' +>>> f.clean('T2S 2Z7') +u'T2S 2Z7' +>>> f.clean('F2S 2H3') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('A2S 2D3') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('A2I 2R3') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('A2I 2R3') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('A2Q 2R3') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('U2B 2R3') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] +>>> f.clean('O2B 2R3') +Traceback (most recent call last): +... +ValidationError: [u'Enter a postal code in the format XXX XXX.'] # CAPhoneNumberField ##########################################################