Ticket #5670: ukpostcodefield.diff

File ukpostcodefield.diff, 3.7 KB (added by scott@…, 8 years ago)

Patch and tests

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

     
    11"""
    22UK-specific Form helpers
    33"""
     4import re
    45
    5 from django.newforms.fields import RegexField
     6from django.newforms.fields import CharField
     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)
     23
     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
  • tests/regressiontests/forms/localflavor/uk.py

     
    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.']
     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')
     43ValidationError: [u'Enter a valid postcode.']
    3044
    3145>>> f = UKPostcodeField(required=False)
    3246>>> f.clean('BT32 4PX')
     
    3650>>> f.clean('1NV 4L1D')
    3751Traceback (most recent call last):
    3852...
    39 ValidationError: [u'Enter a postcode. A space is required between the two postcode parts.']
     53ValidationError: [u'Enter a valid postcode.']
    4054>>> 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.']
     55u'BT32 4PX'
    4456>>> f.clean(None)
    4557u''
    4658>>> f.clean('')
Back to Top