Ticket #12710: localflavor_kr.diff

File localflavor_kr.diff, 5.4 KB (added by KwonHan Bae, 14 years ago)
  • django/contrib/localflavor/kr/kr_city_and_province.py

     
     1# -*- coding: utf-8 -*
     2
     3CITY_AND_PROVINCE_CHOICES = (
     4    ('서울', '서울특별시'),
     5    ('부산', '부산광역시'),
     6    ('대구', '대구광역시'),
     7    ('인천', '인천광역시'),
     8    ('광주', '광주광역시'),
     9    ('대전', '대전광역시'),
     10    ('울산', '울산광역시'),
     11    ('경기', '경기도'),
     12    ('강원', '강원도'),
     13    ('충북', '충청북도'),
     14    ('충남', '충청남도'),
     15    ('전북', '전라북도'),
     16    ('전남', '전라남도'),
     17    ('경북', '경상북도'),
     18    ('경남', '경상남도'),
     19    ('제주', '제주도'),
     20)
  • django/contrib/localflavor/kr/forms.py

     
     1"""
     2Korea-specific Form helpers
     3"""
     4
     5from django.core.validators import EMPTY_VALUES
     6from django.forms import ValidationError
     7from django.forms.fields import Field, RegexField, Select, CharField
     8from django.utils.encoding import smart_unicode
     9from django.utils.translation import ugettext_lazy as _
     10import time
     11import re
     12
     13phone_digits_re = re.compile(r'^(0\d{1,2})[-\.]?(\d{3,4})[-\.]?(\d{4})$')
     14
     15class KRZipCodeField(RegexField):
     16    default_error_messages = {
     17        'invalid': _('Enter a zip code in the format XXXXXX or XXX-XXX.'),
     18    }
     19
     20    def __init__(self, *args, **kwargs):
     21        super(KRZipCodeField, self).__init__(r'^\d{3}-?\d{3}$',
     22            max_length=None, min_length=None, *args, **kwargs)
     23
     24class KRPhoneNumberField(CharField):
     25    """
     26    Korea Phone Number
     27    refer http://ko.wikipedia.org/wiki/%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD%EC%9D%98_%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8_%EC%B2%B4%EA%B3%84
     28
     29    valid examples)
     30        phone)
     31        02-000-0000 or 02000000
     32        055-000-0000 or 0550000000
     33        mobile)
     34        010-0000-0000 or 01000000000
     35        011-000-0000 or 0100000000
     36    """
     37    default_error_messages = {
     38        'invalid': _('Phone numbers must be in 0XX-XXXX-XXXX format.'),
     39    }
     40
     41    def clean(self, value):
     42        super(KRPhoneNumberField, self).clean(value)
     43        if value in EMPTY_VALUES:
     44            return u''
     45        value = re.sub('(\(|\)|\s+)', '', smart_unicode(value))
     46        m = phone_digits_re.search(value)
     47        if m:
     48            return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
     49        raise ValidationError(self.error_messages['invalid'])
     50
     51rrn_re = re.compile(r"^(?P<year>\d{2})(?P<month>\d{2})(?P<day>\d{2})[-\ ]?(?P<sex>[012349])(?P<others>\d{5})(?P<checksum>\d{1})$")
     52class KRResidentRegistrationNumberField(Field):
     53    """
     54    A Korea Resident Registration Number
     55
     56    refer http://ko.wikipedia.org/wiki/%EC%A3%BC%EB%AF%BC%EB%93%B1%EB%A1%9D%EB%B2%88%ED%98%B8
     57
     58    Checks the following rules to determine whether the number is valid:
     59
     60        * Conforms to the %y%m%d-XXXXXXX format.
     61        * First two digit means birth year without century as a decimal number [00,99]
     62        * Second two digit means birth month as a decimal number [01,12].
     63        * Third two digit means birth day of the month as a decimal number [01,31].
     64        * First digit of second part can be [012349] which was mixed with sex and century.
     65        * the other parts are not certain.
     66        * last digit is checksum which can be calcurated by algorithm
     67        * these rules checks format valid only.
     68    """
     69    default_error_messages = {
     70        'invalid': _('Enter a valid Korea Resident Registration Number in XXXXXX-XXXXXXX format.'),
     71    }
     72
     73    def clean(self, value):
     74        super(KRResidentRegistrationNumberField, self).clean(value)
     75        if value in EMPTY_VALUES:
     76            return u''
     77        match = re.match(rrn_re, value)
     78        if not match:
     79            raise ValidationError(self.error_messages['invalid'])
     80        year , month , day , sex , others , checksum = match.groups()
     81
     82        # First pass : year month day combinations
     83        try:
     84            birthday = time.strptime("%s%s%s" % ( year , month , day ) , "%y%m%d")
     85        except ValueError:
     86            raise ValidationError(self.error_messages['invalid'])
     87
     88        # Second pass: checksums
     89        try:
     90            sumsource = zip( map(int,list(match.group().replace("-",""))[:-1]) , [2,3,4,5,6,7,8,9,2,3,4,5] )
     91            new_checksum = ( 11 - ( reduce(lambda x , y : x + y[0] * y[1] , sumsource , 0) % 11 ))%10
     92            if checksum != new_checksum:
     93                raise ValidationError(self.error_messages['invalid'])
     94        except:
     95            raise ValidationError(self.error_messages['invalid'])
     96        return u'%s%s%s-%s%s%s' % ( year , month , day , sex , others , checksum )
     97
     98class KRSpecialCityAndProvinceSelect(Select):
     99    """
     100    A Select widget that uses a list of Korea Special City and provinces as its choices.
     101    """
     102    def __init__(self, attrs=None):
     103        from kr_city_and_province import CITY_AND_PROVINCE_CHOICES
     104        super(KRSpecialCityAndProvinceSelect, self).__init__(attrs, choices=CITY_AND_PROVINCE_CHOICES)
Back to Top