Django

Code

Ticket #5670: ukpostcodefield2.diff

File ukpostcodefield2.diff, 3.8 kB (added by scott@staplefish.com, 1 year ago)

New patch against trunk (includes tests)

  • django/contrib/localflavor/uk/forms.py

    old new  
    11""" 
    22UK-specific Form helpers 
    33""" 
     4import re 
    45 
    5 from django.newforms.fields import RegexField, Select 
     6from django.newforms.fields import CharField, Select 
     7from django.newforms import ValidationError 
    68from django.utils.translation import ugettext 
    79 
    8 class UKPostcodeField(RegexField): 
     10class UKPostcodeField(CharField): 
    911    """ 
    1012    A form field that validates its input is a UK postcode. 
     13     
     14    Uppercases the value and adds space in correct place if required. 
    1115 
    1216    The regular expression used is sourced from the schema for British Standard 
    1317    BS7666 address types: http://www.govtalk.gov.uk/gdsc/schemas/bs7666-v2-0.xsd 
    1418    """ 
    15     def __init__(self, *args, **kwargs): 
    16         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})$', 
    17             max_length=None, min_length=None, 
    18             error_message=ugettext(u'Enter a postcode. A space is required between the two postcode parts.'), 
    19             *args, **kwargs) 
     19    OUTCODE_PATTERN = '[A-PR-UWYZ]([0-9]{1,2}|([A-HIK-Y][0-9](|[0-9]|[ABEHMNPRVWXY]))|[0-9][A-HJKSTUW])' 
     20    INCODE_PATTERN = '[0-9][ABD-HJLNP-UW-Z]{2}' 
     21    POSTCODE_REGEX = re.compile(r'^(GIR 0AA|%s %s)$' % (OUTCODE_PATTERN, INCODE_PATTERN)) 
     22    SPACE_REGEX = re.compile(r' *(%s)$' % INCODE_PATTERN) 
    2023 
     24    def clean(self, value): 
     25        value = super(UKPostcodeField, self).clean(value) 
     26        if value == u'': 
     27            return value 
     28        postcode = value.upper().strip() 
     29        # Put a single space before the incode (second part). 
     30        postcode = self.SPACE_REGEX.sub(r' \1', postcode) 
     31        if not self.POSTCODE_REGEX.search(postcode): 
     32            raise ValidationError(ugettext(u'Enter a valid postcode.')) 
     33        return postcode 
     34 
    2135class UKCountySelect(Select): 
    2236    """ 
    2337    A Select widget that uses a list of UK Counties/Regions as its choices. 
  • tests/regressiontests/forms/localflavor/uk.py

    old new  
    1212>>> f.clean('GIR 0AA') 
    1313u'GIR 0AA' 
    1414>>> f.clean('BT324PX') 
     15u'BT32 4PX' 
     16>>> f.clean('1NV 4L1D') 
    1517Traceback (most recent call last): 
    1618... 
    17 ValidationError: [u'Enter a postcode. A space is required between the two postcode parts.'] 
    18 >>> f.clean('1NV 4L1D') 
     19ValidationError: [u'Enter a valid postcode.'] 
     20>>> f.clean('1NV4L1D') 
    1921Traceback (most recent call last): 
    2022... 
    21 ValidationError: [u'Enter a postcode. A space is required between the two postcode parts.'] 
     23ValidationError: [u'Enter a valid postcode.'] 
    2224>>> f.clean(None) 
    2325Traceback (most recent call last): 
    2426... 
     
    2729Traceback (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') 
    3348u'BT32 4PX' 
     
    3651>>> f.clean('1NV 4L1D') 
    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'' 
    4659>>> f.clean('')