Ticket #9289: django_localflavor_se_r6.diff

File django_localflavor_se_r6.diff, 23.1 KB (added by Ludvig Ericson, 16 years ago)

Marked strings for translation, because some languages have non-roman alphabets.

  • django/contrib/localflavor/se/se_counties.py

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

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

     
     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) as its
     17    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,
     26                                             choices=COUNTY_CHOICES)
     27
     28class SEOrganisationNumberField(forms.CharField):
     29    """
     30    A form field that validates input as a Swedish organisation number
     31    (organisationsnummer).
     32
     33    It accepts the same input as SEPersonalIdentityField (for sole
     34    proprietorships (enskild firma). However, co-ordination numbers are not
     35    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    A + indicates that the person is older than 100 years, which will be taken
     85    into consideration when the date is validated.
     86   
     87    The checksum will be calculated and checked. The birth date is checked to
     88    be a valid date.
     89
     90    By default, co-ordination numbers (samordningsnummer) will be accepted. To
     91    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, coordination_number=True, *args, **kwargs):
     98        self.coordination_number = coordination_number
     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(' ', '')
  • tests/regressiontests/forms/localflavor/se.py

     
     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</option>\n<option value="AC">V\xe4sterbotten</option>\n<option value="BD">Norrbotten</option>\n<option value="C">Uppsala</option>\n<option value="D">S\xf6dermanland</option>\n<option value="E" selected="selected">\xd6sterg\xf6tland</option>\n<option value="F">J\xf6nk\xf6ping</option>\n<option value="G">Kronoberg</option>\n<option value="H">Kalmar</option>\n<option value="I">Gotland</option>\n<option value="K">Blekinge</option>\n<option value="M">Sk\xe5ne</option>\n<option value="N">Halland</option>\n<option value="O">V\xe4stra G\xf6taland</option>\n<option value="S">V\xe4rmland</option>\n<option value="T">\xd6rebro</option>\n<option value="U">V\xe4stmanland</option>\n<option value="W">Dalarna</option>\n<option value="X">G\xe4vleborg</option>\n<option value="Y">V\xe4sternorrland</option>\n<option value="Z">J\xe4mtland</option>\n</select>'
     24
     25# SEOrganisationNumberField #######################################
     26
     27>>> from django.contrib.localflavor.se.forms import SEOrganisationNumberField
     28
     29>>> f = SEOrganisationNumberField()
     30
     31# Ordinary personal identity numbers for sole proprietors
     32# The same rules as for SEPersonalIdentityField applies here
     33>>> f.clean('870512-1989')
     34u'198705121989'
     35>>> f.clean('19870512-1989')
     36u'198705121989'
     37>>> f.clean('870512-2128')
     38u'198705122128'
     39>>> f.clean('081015-6315')
     40u'190810156315'
     41>>> f.clean('081015+6315')
     42u'180810156315'
     43>>> f.clean('0810156315')
     44u'190810156315'
     45
     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# Faux organisation number, which tests that the checksum can be 0
     112>>> f.clean('232518-5060')
     113u'2325185060'
     114
     115>>> f.clean('556074+3089') # Volvo Personvagnar, bad format
     116Traceback (most recent call last):
     117...
     118ValidationError: [u'Enter a valid Swedish organisation number.']
     119
     120
     121# Invalid checksum
     122>>> f.clean('2120000441')
     123Traceback (most recent call last):
     124...
     125ValidationError: [u'Enter a valid Swedish organisation number.']
     126
     127# Valid checksum but invalid organisation type
     128f.clean('1120000441')
     129Traceback (most recent call last):
     130...
     131ValidationError: [u'Enter a valid Swedish organisation number.']
     132
     133# Empty values with required=False
     134>>> f = SEOrganisationNumberField(required=False)
     135
     136>>> f.clean(None)
     137u''
     138
     139>>> f.clean('')
     140u''
     141
     142
     143# SEPersonalIdentityNumberField #######################################
     144
     145>>> from django.contrib.localflavor.se.forms import SEPersonalIdentityNumberField
     146
     147>>> f = SEPersonalIdentityNumberField()
     148
     149# Valid id numbers
     150>>> f.clean('870512-1989')
     151u'198705121989'
     152
     153>>> f.clean('870512-2128')
     154u'198705122128'
     155
     156>>> f.clean('19870512-1989')
     157u'198705121989'
     158
     159>>> f.clean('198705121989')
     160u'198705121989'
     161
     162>>> f.clean('081015-6315')
     163u'190810156315'
     164
     165>>> f.clean('0810156315')
     166u'190810156315'
     167
     168# This is a "special-case" in the checksum calculation,
     169# where the sum is divisible by 10 (the checksum digit == 0)
     170>>> f.clean('8705141060')
     171u'198705141060'
     172
     173# + means that the person is older than 100 years
     174>>> f.clean('081015+6315')
     175u'180810156315'
     176
     177# Bogus values
     178>>> f.clean('081015 6315')
     179Traceback (most recent call last):
     180...
     181ValidationError: [u'Enter a valid Swedish personal identity number.']
     182
     183>>> f.clean('950d314496')
     184Traceback (most recent call last):
     185...
     186ValidationError: [u'Enter a valid Swedish personal identity number.']
     187
     188>>> f.clean('invalid!!!')
     189Traceback (most recent call last):
     190...
     191ValidationError: [u'Enter a valid Swedish personal identity number.']
     192
     193
     194# Invalid dates
     195
     196# February 31st does not exist
     197>>> f.clean('950231-4496')
     198Traceback (most recent call last):
     199...
     200ValidationError: [u'Enter a valid Swedish personal identity number.']
     201
     202# Month 14 does not exist
     203>>> f.clean('6914104499')
     204Traceback (most recent call last):
     205...
     206ValidationError: [u'Enter a valid Swedish personal identity number.']
     207
     208# There are no Swedish personal id numbers where year < 1800
     209>>> f.clean('17430309-7135')
     210Traceback (most recent call last):
     211...
     212ValidationError: [u'Enter a valid Swedish personal identity number.']
     213
     214# Invalid checksum
     215>>> f.clean('870514-1111')
     216Traceback (most recent call last):
     217...
     218ValidationError: [u'Enter a valid Swedish personal identity number.']
     219
     220# Empty values
     221>>> f.clean('')
     222Traceback (most recent call last):
     223...
     224ValidationError: [u'This field is required.']
     225
     226>>> f.clean(None)
     227Traceback (most recent call last):
     228...
     229ValidationError: [u'This field is required.']
     230
     231# Co-ordination number checking
     232>>> f.clean('870574-1315')
     233u'198705741315'
     234
     235>>> f.clean('870574+1315')
     236u'188705741315'
     237
     238>>> f.clean('198705741315')
     239u'198705741315'
     240
     241# Co-ordination number with bad checksum
     242>>> f.clean('870573-1311')
     243Traceback (most recent call last):
     244...
     245ValidationError: [u'Enter a valid Swedish personal identity number.']
     246
     247
     248# Check valid co-ordination numbers, that should not be accepted
     249# because of coordination_number=False
     250>>> f = SEPersonalIdentityNumberField(coordination_number=False)
     251
     252>>> f.clean('870574-1315')
     253Traceback (most recent call last):
     254...
     255ValidationError: [u'Co-ordination numbers are not allowed.']
     256
     257>>> f.clean('870574+1315')
     258Traceback (most recent call last):
     259...
     260ValidationError: [u'Co-ordination numbers are not allowed.']
     261
     262>>> f.clean('8705741315')
     263Traceback (most recent call last):
     264...
     265ValidationError: [u'Co-ordination numbers are not allowed.']
     266
     267# Invalid co-ordination numbers should be treated as invalid, and not
     268# as co-ordination numbers
     269>>> f.clean('870573-1311')
     270Traceback (most recent call last):
     271...
     272ValidationError: [u'Enter a valid Swedish personal identity number.']
     273
     274# Empty values with required=False
     275>>> f = SEPersonalIdentityNumberField(required=False)
     276
     277>>> f.clean(None)
     278u''
     279
     280>>> f.clean('')
     281u''
     282
     283# SEPostalCodeField ###############################################
     284>>> from django.contrib.localflavor.se.forms import SEPostalCodeField
     285>>> f = SEPostalCodeField()
     286>>>
     287Postal codes can have spaces
     288>>> f.clean('589 37')
     289u'58937'
     290
     291... but the dont have to
     292>>> f.clean('58937')
     293u'58937'
     294>>> f.clean('abcasfassadf')
     295Traceback (most recent call last):
     296...
     297ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
     298
     299# Only one space is allowed for separation
     300>>> f.clean('589  37')
     301Traceback (most recent call last):
     302...
     303ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
     304
     305# The postal code must not start with 0
     306>>> f.clean('01234')
     307Traceback (most recent call last):
     308...
     309ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
     310
     311# Empty values
     312>>> f.clean('')
     313Traceback (most recent call last):
     314...
     315ValidationError: [u'This field is required.']
     316
     317>>> f.clean(None)
     318Traceback (most recent call last):
     319...
     320ValidationError: [u'This field is required.']
     321
     322# Empty values, required=False
     323>>> f = SEPostalCodeField(required=False)
     324>>> f.clean('')
     325u''
     326>>> f.clean(None)
     327u''
     328
     329# Revert the monkey patching
     330>>> datetime.date = olddate
     331
     332"""
  • tests/regressiontests/forms/tests.py

     
    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
     
    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,
  • AUTHORS

     
    300300    Carlos Eduardo de Paula <carlosedp@gmail.com>
    301301    pavithran s <pavithran.s@gmail.com>
    302302    Barry Pederson <bp@barryp.org>
     303    Andreas Pelme <andreas@pelme.se>
    303304    permonik@mesias.brnonet.cz
    304305    peter@mymart.com
    305306    pgross@thoughtworks.com
  • docs/ref/contrib/localflavor.txt

     
    6060    * Slovakia_
    6161    * `South Africa`_
    6262    * Spain_
     63    * Sweden_
    6364    * Switzerland_
    6465    * `United Kingdom`_
    6566    * `United States of America`_
     
    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)`_
     
    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) as its
     584    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    It accepts the same input as SEPersonalIdentityField (for sole
     595    proprietorships (enskild firma). However, co-ordination numbers are not
     596    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    A \+ indicates that the person is older than 100 years, which will be taken
     613    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. To
     619    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
Back to Top