Django

Code

Changeset 6952

Show
Ignore:
Timestamp:
12/18/07 22:43:47 (9 months ago)
Author:
mtredinnick
Message:

Fixed #5670 -- Changed the validation of the UK postcode widget to allow for easier input. Normalisation still returns the same things as previously. Patch from scott@staplefish.com.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/contrib/localflavor/uk/forms.py

    r6926 r6952  
    33""" 
    44 
    5 from django.newforms.fields import RegexField, Select 
     5import re 
     6 
     7from django.newforms.fields import CharField, Select 
     8from django.newforms import ValidationError 
    69from django.utils.translation import ugettext 
    710 
    8 class UKPostcodeField(RegexField): 
     11class UKPostcodeField(CharField): 
    912    """ 
    1013    A form field that validates its input is a UK postcode. 
     
    1215    The regular expression used is sourced from the schema for British Standard 
    1316    BS7666 address types: http://www.govtalk.gov.uk/gdsc/schemas/bs7666-v2-0.xsd 
     17 
     18    The value is uppercased and a space added in the correct place, if required. 
    1419    """ 
    1520    default_error_messages = { 
    16         'invalid': ugettext(u'Enter a postcode. A space is required between the two postcode parts.'), 
     21        'invalid': ugettext(u'Enter a valid postcode.'), 
    1722    } 
     23    outcode_pattern = '[A-PR-UWYZ]([0-9]{1,2}|([A-HIK-Y][0-9](|[0-9]|[ABEHMNPRVWXY]))|[0-9][A-HJKSTUW])' 
     24    incode_pattern = '[0-9][ABD-HJLNP-UW-Z]{2}' 
     25    postcode_regex = re.compile(r'^(GIR 0AA|%s %s)$' % (outcode_pattern, incode_pattern)) 
     26    space_regex = re.compile(r' *(%s)$' % incode_pattern) 
    1827 
    19     def __init__(self, *args, **kwargs): 
    20         super(UKPostcodeField, self).__init__(r'^(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HIK-Y][0-9](|[0-9]|[ABEHMNPRVWXY]))|[0-9][A-HJKSTUW]) [0-9][ABD-HJLNP-UW-Z]{2})$', 
    21             max_length=None, min_length=None, *args, **kwargs) 
     28    def clean(self, value): 
     29        value = super(UKPostcodeField, self).clean(value) 
     30        if value == u'': 
     31            return value 
     32        postcode = value.upper().strip() 
     33        # Put a single space before the incode (second part). 
     34        postcode = self.space_regex.sub(r' \1', postcode) 
     35        if not self.postcode_regex.search(postcode): 
     36            raise ValidationError(self.default_error_messages['invalid']) 
     37        return postcode 
    2238 
    2339class UKCountySelect(Select): 
  • django/trunk/tests/regressiontests/forms/localflavor/uk.py

    r6379 r6952  
    1313u'GIR 0AA' 
    1414>>> f.clean('BT324PX') 
    15 Traceback (most recent call last): 
    16 ... 
    17 ValidationError: [u'Enter a postcode. A space is required between the two postcode parts.'] 
     15u'BT32 4PX' 
    1816>>> f.clean('1NV 4L1D') 
    1917Traceback (most recent call last): 
    2018... 
    21 ValidationError: [u'Enter a postcode. A space is required between the two postcode parts.'] 
     19ValidationError: [u'Enter a valid postcode.'] 
     20>>> f.clean('1NV4L1D') 
     21Traceback (most recent call last): 
     22... 
     23ValidationError: [u'Enter a valid postcode.'] 
    2224>>> f.clean(None) 
    2325Traceback (most recent call last): 
     
    2830... 
    2931ValidationError: [u'This field is required.'] 
    30  
     32>>> f.clean(' so11aa ') 
     33u'SO1 1AA' 
     34>>> f.clean(' so1  1aa ') 
     35u'SO1 1AA' 
     36>>> f.clean('G2 3wt') 
     37u'G2 3WT' 
     38>>> f.clean('EC1A 1BB') 
     39u'EC1A 1BB' 
     40>>> f.clean('Ec1a1BB') 
     41u'EC1A 1BB' 
     42>>> f.clean(' b0gUS') 
     43Traceback (most recent call last): 
     44... 
     45ValidationError: [u'Enter a valid postcode.'] 
    3146>>> f = UKPostcodeField(required=False) 
    3247>>> f.clean('BT32 4PX') 
     
    3752Traceback (most recent call last): 
    3853... 
    39 ValidationError: [u'Enter a postcode. A space is required between the two postcode parts.'] 
     54ValidationError: [u'Enter a valid postcode.'] 
    4055>>> f.clean('BT324PX') 
    41 Traceback (most recent call last): 
    42 ... 
    43 ValidationError: [u'Enter a postcode. A space is required between the two postcode parts.'] 
     56u'BT32 4PX' 
    4457>>> f.clean(None) 
    4558u''