Ticket #9289: django_localflavor_se_r2.diff

File django_localflavor_se_r2.diff, 23.2 KB (added by peritus, 6 years ago)

Updated patch

  • AUTHORS

    diff --git a/AUTHORS b/AUTHORS
    index 7bbec38..558f0ff 100644
    a b answer newbie questions, and generally made Django that much better: 
    297297    Carlos Eduardo de Paula <carlosedp@gmail.com>
    298298    pavithran s <pavithran.s@gmail.com>
    299299    Barry Pederson <bp@barryp.org>
     300    Andreas Pelme <andreas@pelme.se>
    300301    permonik@mesias.brnonet.cz
    301302    peter@mymart.com
    302303    pgross@thoughtworks.com
  • new file django/contrib/localflavor/se/forms.py

    diff --git a/django/contrib/localflavor/se/__init__.py b/django/contrib/localflavor/se/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/django/contrib/localflavor/se/forms.py b/django/contrib/localflavor/se/forms.py
    new file mode 100644
    index 0000000..84233c8
    - +  
     1# -*- coding: utf-8 -*-
     2"""
     3Swedish specific Form helpers
     4"""
     5
     6from django import forms
     7from django.utils.translation import ugettext_lazy as _
     8from django.forms.fields import EMPTY_VALUES
     9
     10from utils import *
     11
     12__all__ = ('SECountySelect', 'SEOrganisationNumberField', 'SEPersonalIdentityNumberField', 'SEPostalCodeField')
     13
     14class SECountySelect(forms.Select):
     15    """
     16    A Select form widget that uses a list of the Swedish counties (län)
     17    as its choices.
     18
     19    The cleaned value is the official county code -- see
     20    http://en.wikipedia.org/wiki/Counties_of_Sweden for a list.
     21    """
     22
     23    def __init__(self, attrs=None):
     24        from se_counties import COUNTY_CHOICES
     25        super(SECountySelect, self).__init__(attrs=attrs, choices=COUNTY_CHOICES)
     26
     27
     28class SEOrganisationNumberField(forms.CharField):
     29    """
     30    A form field that validates input as a Swedish organisation number
     31    (organisationsnummer).
     32
     33    This fields accepts the same input as SEPersonalIdentityField (for
     34    sole proprietorships (enskild firma)). However, co-ordination numbers are
     35    not accepted.
     36
     37    It also accepts ordinary Swedish organisation numbers with the format
     38    NNNNNNNNNN.
     39
     40    The return value will be YYYYMMDDXXXX for sole proprietors, and NNNNNNNNNN
     41    for other organisations.
     42    """
     43
     44    default_error_messages = {
     45        'invalid': _('Enter a valid Swedish organisation number.'),
     46    }
     47
     48    def clean(self, value):
     49        value = super(SEOrganisationNumberField, self).clean(value)
     50       
     51        if value in EMPTY_VALUES:
     52            return u''
     53       
     54        match = SWEDISH_ID_NUMBER.match(value)
     55        if not match:
     56            raise forms.ValidationError(self.error_messages['invalid'])
     57
     58        gd = match.groupdict()
     59       
     60        # Compare the calculated value with the checksum
     61        if id_number_checksum(gd) != int(gd['checksum']):
     62            raise forms.ValidationError(self.error_messages['invalid'])
     63       
     64        # First: check if this is a real organisation_number
     65        if valid_organisation(gd):
     66            return format_organisation_number(gd)
     67
     68        # Is this a single properitor (enskild firma)?
     69        try:
     70            birth_day = validate_id_birthday(gd, False)
     71            return format_personal_id_number(birth_day, gd)
     72        except ValueError:
     73            raise forms.ValidationError(self.error_messages['invalid'])
     74
     75
     76class SEPersonalIdentityNumberField(forms.CharField):
     77    """
     78    A form field that validates input as a Swedish personal identity number
     79    (personnummer).
     80
     81    The correct formats are YYYYMMDD-XXXX, YYYYMMDDXXXX, YYMMDD-XXXX,
     82    YYMMDDXXXX and YYMMDD+XXXX.
     83
     84    + indicates that the person is older than 100 years, which will be
     85    taken into consideration when the date is validated.
     86   
     87    The checksum will be calculated and checked. The birth date is checked
     88    to be a valid date.
     89
     90    By default, co-ordination numbers (samordningsnummer) will be accepted.
     91    To only allow real personal identity numbers, pass the keyword argument
     92    coordination_number=False to the constructor.
     93
     94    The cleaned value will always have the format YYYYMMDDXXXX.
     95    """
     96
     97    def __init__(self, *args, **kwargs):
     98        self.coordination_number = kwargs.pop('coordination_number', True)
     99        super(SEPersonalIdentityNumberField, self).__init__(*args, **kwargs)
     100
     101    default_error_messages = {
     102        'invalid': _('Enter a valid Swedish personal identity number.'),
     103        'coordination_number': _('Co-ordination numbers are not allowed.'),
     104    }
     105
     106    def clean(self, value):
     107        value = super(SEPersonalIdentityNumberField, self).clean(value)
     108
     109        if value in EMPTY_VALUES:
     110            return u''
     111 
     112        match = SWEDISH_ID_NUMBER.match(value)
     113        if match is None:
     114            raise forms.ValidationError(self.error_messages['invalid'])
     115
     116        gd = match.groupdict()
     117 
     118        # compare the calculated value with the checksum
     119        if id_number_checksum(gd) != int(gd['checksum']):
     120            raise forms.ValidationError(self.error_messages['invalid'])
     121
     122        # check for valid birthday
     123        try:
     124            birth_day = validate_id_birthday(gd)
     125        except ValueError:
     126            raise forms.ValidationError(self.error_messages['invalid'])
     127
     128        # make sure that co-ordination numbers do not pass if not allowed
     129        if not self.coordination_number and int(gd['day']) > 60:
     130            raise forms.ValidationError(self.error_messages['coordination_number'])
     131 
     132        return format_personal_id_number(birth_day, gd)
     133
     134
     135class SEPostalCodeField(forms.RegexField):
     136    """
     137    A form field that validates input as a Swedish postal code (postnummer).
     138    Valid codes consist of five digits (XXXXX). The number can optionally be
     139    formatted with a space after the third digit (XXX XX).
     140
     141    The cleaned value will never contain the space.
     142    """
     143
     144    default_error_messages = {
     145        'invalid': _('Enter a Swedish postal code in the format XXXXX.'),
     146    }
     147
     148    def __init__(self, *args, **kwargs):
     149        super(SEPostalCodeField, self).__init__(SE_POSTAL_CODE, *args, **kwargs)
     150
     151    def clean(self, value):
     152        return super(SEPostalCodeField, self).clean(value).replace(' ', '')
     153
  • new file django/contrib/localflavor/se/se_counties.py

    diff --git a/django/contrib/localflavor/se/se_counties.py b/django/contrib/localflavor/se/se_counties.py
    new file mode 100644
    index 0000000..0944064
    - +  
     1# -*- coding: utf-8 -*-
     2"""
     3A alphabetical list of Swedish counties, sorted by county codes.
     4
     5
     6http://en.wikipedia.org/wiki/Counties_of_Sweden
     7
     8This exists in this standalone file so that it's only imported into memory
     9when explicitly needed.
     10
     11"""
     12
     13from django.utils.translation import ugettext_lazy as _
     14
     15COUNTY_CHOICES = (
     16    ('AB', _(u'Stockholm County')),
     17    ('AC', _(u'Västerbotten County')),
     18    ('BD', _(u'Norrbotten County')),
     19    ('C', _(u'Uppsala County')),
     20    ('D', _(u'Södermanland County')),
     21    ('E', _(u'Östergötland County')),
     22    ('F', _(u'Jönköping County')),
     23    ('G', _(u'Kronoberg County')),
     24    ('H', _(u'Kalmar County')),
     25    ('I', _(u'Gotland County')),
     26    ('K', _(u'Blekinge County')),
     27    ('M', _(u'Skåne County')),
     28    ('N', _(u'Halland County')),
     29    ('O', _(u'Västra Götaland County')),
     30    ('S', _(u'Värmland County')),
     31    ('T', _(u'Örebro County')),
     32    ('U', _(u'Västmanland County')),
     33    ('W', _(u'Dalarna County')),
     34    ('X', _(u'Gävleborg County')),
     35    ('Y', _(u'Västernorrland County')),
     36    ('Z', _(u'Jämtland County')),
     37)
  • new file django/contrib/localflavor/se/utils.py

    diff --git a/django/contrib/localflavor/se/utils.py b/django/contrib/localflavor/se/utils.py
    new file mode 100644
    index 0000000..cd3eb0f
    - +  
     1import re
     2import datetime
     3
     4SWEDISH_ID_NUMBER = re.compile(r'^(?P<century>\d{2})?(?P<year>\d{2})(?P<month>\d{2})(?P<day>\d{2})(?P<sign>[\-+])?(?P<serial>\d{3})(?P<checksum>\d)$')
     5SE_POSTAL_CODE = re.compile(r'^[1-9]\d{2} ?\d{2}$')
     6
     7def id_number_checksum(gd):
     8    """
     9    Calculates a Swedish id number checksum, using the
     10    "Luhn"-algoritm
     11    """
     12
     13    n = s = 0
     14    for c in (gd['year'] + gd['month'] + gd['day'] + gd['serial']):
     15        tmp = ((n % 2) and 1 or 2) * int(c)
     16        if tmp > 9:
     17            tmp = sum([int(i) for i in str(tmp)])
     18 
     19        s += tmp
     20        n += 1
     21 
     22    return (((s / 10) + 1) * 10) - s
     23
     24def validate_id_birthday(gd, fix_coordination_number_day=True):
     25    """
     26    Validates the birth_day and returns the datetime.date object for
     27    the birth_day.
     28
     29    If the date is an invalid birth day, a ValueError will be raised.
     30    """
     31   
     32    today = datetime.date.today()
     33   
     34    day = int(gd['day'])
     35    if fix_coordination_number_day and day > 60:
     36        day -= 60
     37
     38    if gd['century'] is None:
     39
     40        # The century was not specified, and need to be calculated from todays date
     41        current_year = today.year
     42        year = int(today.strftime('%Y')) - int(today.strftime('%y')) + int(gd['year'])
     43   
     44        if ('%s%s%02d' % (gd['year'], gd['month'], day)) > today.strftime('%y%m%d'):
     45            year -= 100
     46
     47        # If the person is older than 100 years
     48        if gd['sign'] == '+':
     49            year -= 100
     50    else:
     51        year = int(gd['century'] + gd['year'])
     52       
     53        # Make sure the year is valid
     54        # There are no swedish personal identity numbers where year < 1800
     55        if year < 1800:
     56            raise ValueError
     57
     58    # ValueError will be raise for invalid dates
     59    birth_day = datetime.date(year, int(gd['month']), day)
     60   
     61    # birth_day must not be in the future
     62    if birth_day > today:
     63        raise ValueError
     64   
     65    return birth_day
     66
     67def format_personal_id_number(birth_day, gd):
     68    # birth_day.strftime cannot be used, since it does not support dates < 1900
     69    return unicode(str(birth_day.year) + gd['month'] + gd['day'] + gd['serial'] + gd['checksum'])
     70
     71def format_organisation_number(gd):
     72    if gd['century'] is None:
     73        century = ''
     74    else:
     75        century = gd['century']
     76
     77    return unicode(century + gd['year'] + gd['month'] + gd['day'] + gd['serial'] + gd['checksum'])
     78
     79def valid_organisation(gd):
     80    return gd['century'] in (None, 16) and \
     81        int(gd['month']) >= 20 and \
     82        gd['sign'] in (None, '-') and \
     83        gd['year'][0] in ('2', '5', '7', '8', '9') # group identifier
     84
  • docs/ref/contrib/localflavor.txt

    diff --git a/docs/ref/contrib/localflavor.txt b/docs/ref/contrib/localflavor.txt
    index 6771efc..93c8f42 100644
    a b Countries currently supported by :mod:`~django.contrib.localflavor` are: 
    6060    * Slovakia_
    6161    * `South Africa`_
    6262    * Spain_
     63    * Sweden_
    6364    * Switzerland_
    6465    * `United Kingdom`_
    6566    * `United States of America`_
    Here's an example of how to use them:: 
    99100.. _Slovakia: `Slovakia (sk)`_
    100101.. _South Africa: `South Africa (za)`_
    101102.. _Spain: `Spain (es)`_
     103.. _Sweden: `Sweden (se)`_
    102104.. _Switzerland: `Switzerland (ch)`_
    103105.. _United Kingdom: `United Kingdom (uk)`_
    104106.. _United States of America: `United States of America (us)`_
    Spain (``es``) 
    573575
    574576    A ``Select`` widget that uses a list of Spanish regions as its choices.
    575577
     578Sweden (``se``)
     579===============
     580
     581.. class:: se.forms.SECountySelect
     582
     583    A Select form widget that uses a list of the Swedish counties (län)
     584    as its choices.
     585
     586    The cleaned value is the official county code -- see
     587    http://en.wikipedia.org/wiki/Counties_of_Sweden for a list.
     588
     589.. class:: se.forms.SEOrganisationNumber
     590
     591    A form field that validates input as a Swedish organisation number
     592    (organisationsnummer).
     593
     594    This fields accepts the same input as SEPersonalIdentityField (for
     595    sole proprietorships (enskild firma)). However, co-ordination numbers are
     596    not accepted.
     597
     598    It also accepts ordinary Swedish organisation numbers with the format
     599    NNNNNNNNNN.
     600
     601    The return value will be YYYYMMDDXXXX for sole proprietors, and NNNNNNNNNN
     602    for other organisations.
     603
     604.. class:: se.forms.SEPersonalIdentityNumber
     605
     606    A form field that validates input as a Swedish personal identity number
     607    (personnummer).
     608
     609    The correct formats are YYYYMMDD-XXXX, YYYYMMDDXXXX, YYMMDD-XXXX,
     610    YYMMDDXXXX and YYMMDD+XXXX.
     611
     612    \+ indicates that the person is older than 100 years, which will be
     613    taken into consideration when the date is validated.
     614   
     615    The checksum will be calculated and checked. The birth date is checked
     616    to be a valid date.
     617
     618    By default, co-ordination numbers (samordningsnummer) will be accepted.
     619    To only allow real personal identity numbers, pass the keyword argument
     620    coordination_number=False to the constructor.
     621
     622    The cleaned value will always have the format YYYYMMDDXXXX.
     623
     624.. class:: se.forms.SEPostalCodeField
     625
     626    A form field that validates input as a Swedish postal code (postnummer).
     627    Valid codes consist of five digits (XXXXX). The number can optionally be
     628    formatted with a space after the third digit (XXX XX).
     629
     630    The cleaned value will never contain the space.
     631
    576632Switzerland (``ch``)
    577633====================
    578634
  • new file tests/regressiontests/forms/localflavor/se.py

    diff --git a/tests/regressiontests/forms/localflavor/se.py b/tests/regressiontests/forms/localflavor/se.py
    new file mode 100644
    index 0000000..ad819e7
    - +  
     1# -*- coding: utf-8 -*-
     2# Tests for the contrib/localflavor/se form fields.
     3
     4tests = r"""
     5# Monkey-patch datetime.date
     6>>> import datetime
     7>>> class MockDate(datetime.date):
     8...     def today(cls):
     9...         return datetime.date(2008, 5, 14)
     10...     today = classmethod(today)
     11...
     12>>> olddate = datetime.date
     13>>> datetime.date = MockDate
     14>>> datetime.date.today()
     15MockDate(2008, 5, 14)
     16
     17
     18# SECountySelect #####################################################
     19>>> from django.contrib.localflavor.se.forms import SECountySelect
     20
     21>>> w = SECountySelect()
     22>>> w.render('swedish_county', 'E')
     23u'<select name="swedish_county">\n<option value="AB">Stockholm County</option>\n<option value="AC">V\xe4sterbotten County</option>\n<option value="BD">Norrbotten County</option>\n<option value="C">Uppsala County</option>\n<option value="D">S\xf6dermanland County</option>\n<option value="E" selected="selected">\xd6sterg\xf6tland County</option>\n<option value="F">J\xf6nk\xf6ping County</option>\n<option value="G">Kronoberg County</option>\n<option value="H">Kalmar County</option>\n<option value="I">Gotland County</option>\n<option value="K">Blekinge County</option>\n<option value="M">Sk\xe5ne County</option>\n<option value="N">Halland County</option>\n<option value="O">V\xe4stra G\xf6taland County</option>\n<option value="S">V\xe4rmland County</option>\n<option value="T">\xd6rebro County</option>\n<option value="U">V\xe4stmanland County</option>\n<option value="W">Dalarna County</option>\n<option value="X">G\xe4vleborg County</option>\n<option value="Y">V\xe4sternorrland County</option>\n<option value="Z">J\xe4mtland County</option>\n</select>'
     24
     25
     26# SEOrganisationNumberField #######################################
     27
     28>>> from django.contrib.localflavor.se.forms import SEOrganisationNumberField
     29
     30>>> f = SEOrganisationNumberField()
     31
     32# Ordinary personal identity numbers for sole proprietors
     33# The same rules as for SEPersonalIdentityField applies here
     34>>> f.clean('870512-1989')
     35u'198705121989'
     36>>> f.clean('19870512-1989')
     37u'198705121989'
     38>>> f.clean('870512-2128')
     39u'198705122128'
     40>>> f.clean('081015-6315')
     41u'190810156315'
     42>>> f.clean('081015+6315')
     43u'180810156315'
     44>>> f.clean('0810156315')
     45u'190810156315'
     46>>> f.clean('081015 6315')
     47Traceback (most recent call last):
     48...
     49ValidationError: [u'Enter a valid Swedish organisation number.']
     50>>> f.clean('950231-4496')
     51Traceback (most recent call last):
     52...
     53ValidationError: [u'Enter a valid Swedish organisation number.']
     54>>> f.clean('6914104499')
     55Traceback (most recent call last):
     56...
     57ValidationError: [u'Enter a valid Swedish organisation number.']
     58>>> f.clean('950d314496')
     59Traceback (most recent call last):
     60...
     61ValidationError: [u'Enter a valid Swedish organisation number.']
     62>>> f.clean('invalid!!!')
     63Traceback (most recent call last):
     64...
     65ValidationError: [u'Enter a valid Swedish organisation number.']
     66>>> f.clean('870514-1111')
     67Traceback (most recent call last):
     68...
     69ValidationError: [u'Enter a valid Swedish organisation number.']
     70
     71
     72# Empty values
     73>>> f.clean('')
     74Traceback (most recent call last):
     75...
     76ValidationError: [u'This field is required.']
     77
     78>>> f.clean(None)
     79Traceback (most recent call last):
     80...
     81ValidationError: [u'This field is required.']
     82
     83# Co-ordination number checking
     84# Co-ordination numbers are not valid organisation numbers
     85>>> f.clean('870574-1315')
     86Traceback (most recent call last):
     87...
     88ValidationError: [u'Enter a valid Swedish organisation number.']
     89
     90>>> f.clean('870573-1311')
     91Traceback (most recent call last):
     92...
     93ValidationError: [u'Enter a valid Swedish organisation number.']
     94
     95# Test some different organisation numbers
     96>>> f.clean('556074-7569') # IKEA Linköping
     97u'5560747569'
     98
     99>>> f.clean('556074-3089') # Volvo Personvagnar
     100u'5560743089'
     101
     102>>> f.clean('822001-5476') # LJS (organisation)
     103u'8220015476'
     104
     105>>> f.clean('8220015476') # LJS (organisation)
     106u'8220015476'
     107
     108>>> f.clean('2120000449') # Katedralskolan Linköping (school)
     109u'2120000449'
     110
     111>>> f.clean('556074+3089') # Volvo Personvagnar, bad format
     112Traceback (most recent call last):
     113...
     114ValidationError: [u'Enter a valid Swedish organisation number.']
     115
     116
     117# Invalid checksum
     118>>> f.clean('2120000441')
     119Traceback (most recent call last):
     120...
     121ValidationError: [u'Enter a valid Swedish organisation number.']
     122
     123# Valid checksum but invalid organisation type
     124f.clean('1120000441')
     125Traceback (most recent call last):
     126...
     127ValidationError: [u'Enter a valid Swedish organisation number.']
     128
     129# Empty values with required=False
     130>>> f = SEOrganisationNumberField(required=False)
     131
     132>>> f.clean(None)
     133u''
     134
     135>>> f.clean('')
     136u''
     137
     138
     139# SEPersonalIdentityNumberField #######################################
     140
     141>>> from django.contrib.localflavor.se.forms import SEPersonalIdentityNumberField
     142
     143>>> f = SEPersonalIdentityNumberField()
     144
     145# Valid id numbers
     146>>> f.clean('870512-1989')
     147u'198705121989'
     148
     149>>> f.clean('870512-2128')
     150u'198705122128'
     151
     152>>> f.clean('19870512-1989')
     153u'198705121989'
     154
     155>>> f.clean('198705121989')
     156u'198705121989'
     157
     158>>> f.clean('081015-6315')
     159u'190810156315'
     160
     161>>> f.clean('0810156315')
     162u'190810156315'
     163
     164# + means that the person is older than 100 years
     165>>> f.clean('081015+6315')
     166u'180810156315'
     167
     168# Bogus values
     169>>> f.clean('081015 6315')
     170Traceback (most recent call last):
     171...
     172ValidationError: [u'Enter a valid Swedish personal identity number.']
     173
     174>>> f.clean('950d314496')
     175Traceback (most recent call last):
     176...
     177ValidationError: [u'Enter a valid Swedish personal identity number.']
     178
     179>>> f.clean('invalid!!!')
     180Traceback (most recent call last):
     181...
     182ValidationError: [u'Enter a valid Swedish personal identity number.']
     183
     184
     185# Invalid dates
     186
     187# February 31st does not exist
     188>>> f.clean('950231-4496')
     189Traceback (most recent call last):
     190...
     191ValidationError: [u'Enter a valid Swedish personal identity number.']
     192
     193# Month 14 does not exist
     194>>> f.clean('6914104499')
     195Traceback (most recent call last):
     196...
     197ValidationError: [u'Enter a valid Swedish personal identity number.']
     198
     199# There are no Swedish personal id numbers where year < 1800
     200>>> f.clean('17430309-7135')
     201Traceback (most recent call last):
     202...
     203ValidationError: [u'Enter a valid Swedish personal identity number.']
     204
     205# Invalid checksum
     206>>> f.clean('870514-1111')
     207Traceback (most recent call last):
     208...
     209ValidationError: [u'Enter a valid Swedish personal identity number.']
     210
     211# Empty values
     212>>> f.clean('')
     213Traceback (most recent call last):
     214...
     215ValidationError: [u'This field is required.']
     216
     217>>> f.clean(None)
     218Traceback (most recent call last):
     219...
     220ValidationError: [u'This field is required.']
     221
     222# Co-ordination number checking
     223>>> f.clean('870574-1315')
     224u'198705741315'
     225
     226>>> f.clean('870574+1315')
     227u'188705741315'
     228
     229>>> f.clean('198705741315')
     230u'198705741315'
     231
     232# Co-ordination number with bad checksum
     233>>> f.clean('870573-1311')
     234Traceback (most recent call last):
     235...
     236ValidationError: [u'Enter a valid Swedish personal identity number.']
     237
     238
     239# Check valid co-ordination numbers, that should not be accepted
     240# because of coordination_number=False
     241>>> f = SEPersonalIdentityNumberField(coordination_number=False)
     242
     243>>> f.clean('870574-1315')
     244Traceback (most recent call last):
     245...
     246ValidationError: [u'Co-ordination numbers are not allowed.']
     247
     248>>> f.clean('870574+1315')
     249Traceback (most recent call last):
     250...
     251ValidationError: [u'Co-ordination numbers are not allowed.']
     252
     253>>> f.clean('8705741315')
     254Traceback (most recent call last):
     255...
     256ValidationError: [u'Co-ordination numbers are not allowed.']
     257
     258# Invalid co-ordination numbers should be treated as invalid, and not
     259# as co-ordination numbers
     260>>> f.clean('870573-1311')
     261Traceback (most recent call last):
     262...
     263ValidationError: [u'Enter a valid Swedish personal identity number.']
     264
     265# Empty values with required=False
     266>>> f = SEPersonalIdentityNumberField(required=False)
     267
     268>>> f.clean(None)
     269u''
     270
     271>>> f.clean('')
     272u''
     273
     274# SEPostalCodeField ###############################################
     275>>> from django.contrib.localflavor.se.forms import SEPostalCodeField
     276>>> f = SEPostalCodeField()
     277>>>
     278Postal codes can have spaces
     279>>> f.clean('589 37')
     280u'58937'
     281
     282... but the dont have to
     283>>> f.clean('58937')
     284u'58937'
     285>>> f.clean('abcasfassadf')
     286Traceback (most recent call last):
     287...
     288ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
     289
     290# Only one space is allowed for separation
     291>>> f.clean('589  37')
     292Traceback (most recent call last):
     293...
     294ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
     295
     296# The postal code must not start with 0
     297>>> f.clean('01234')
     298Traceback (most recent call last):
     299...
     300ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
     301
     302# Empty values
     303>>> f.clean('')
     304Traceback (most recent call last):
     305...
     306ValidationError: [u'This field is required.']
     307
     308>>> f.clean(None)
     309Traceback (most recent call last):
     310...
     311ValidationError: [u'This field is required.']
     312
     313# Empty values, required=False
     314>>> f = SEPostalCodeField(required=False)
     315>>> f.clean('')
     316u''
     317>>> f.clean(None)
     318u''
     319
     320# Revert the monkey patching
     321>>> datetime.date = olddate
     322
     323"""
  • tests/regressiontests/forms/tests.py

    diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py
    index 6a8b017..f930003 100644
    a b from localflavor.jp import tests as localflavor_jp_tests 
    2121from localflavor.nl import tests as localflavor_nl_tests
    2222from localflavor.pl import tests as localflavor_pl_tests
    2323from localflavor.ro import tests as localflavor_ro_tests
     24from localflavor.se import tests as localflavor_se_tests
    2425from localflavor.sk import tests as localflavor_sk_tests
    2526from localflavor.uk import tests as localflavor_uk_tests
    2627from localflavor.us import tests as localflavor_us_tests
    __test__ = { 
    5455    'localflavor_nl_tests': localflavor_nl_tests,
    5556    'localflavor_pl_tests': localflavor_pl_tests,
    5657    'localflavor_ro_tests': localflavor_ro_tests,
     58    'localflavor_se_tests': localflavor_se_tests,
    5759    'localflavor_sk_tests': localflavor_sk_tests,
    5860    'localflavor_uk_tests': localflavor_uk_tests,
    5961    'localflavor_us_tests': localflavor_us_tests,
Back to Top