PageRenderTime 6ms CodeModel.GetById 1ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

/django/contrib/localflavor/il/forms.py

https://code.google.com/p/mango-py/
Python | 66 lines | 43 code | 7 blank | 16 comment | 3 complexity | ef611615d1932d77906fef5632156ff5 MD5 | raw file
 1"""
 2Israeli-specific form helpers
 3"""
 4import re
 5
 6from django.core.exceptions import ValidationError
 7from django.core.validators import EMPTY_VALUES
 8from django.forms.fields import RegexField, Field, EMPTY_VALUES
 9from django.utils.checksums import luhn
10from django.utils.translation import ugettext_lazy as _
11
12# Israeli ID numbers consist of up to 8 digits followed by a checksum digit.
13# Numbers which are shorter than 8 digits are effectively left-zero-padded.
14# The checksum digit is occasionally separated from the number by a hyphen,
15# and is calculated using the luhn algorithm.
16#
17# Relevant references:
18#
19# (hebrew) http://he.wikipedia.org/wiki/%D7%9E%D7%A1%D7%A4%D7%A8_%D7%96%D7%94%D7%95%D7%AA_(%D7%99%D7%A9%D7%A8%D7%90%D7%9C)
20# (hebrew) http://he.wikipedia.org/wiki/%D7%A1%D7%A4%D7%A8%D7%AA_%D7%91%D7%99%D7%A7%D7%95%D7%A8%D7%AA
21
22id_number_re = re.compile(r'^(?P<number>\d{1,8})-?(?P<check>\d)$')
23
24class ILPostalCodeField(RegexField):
25    """
26    A form field that validates its input as an Israeli postal code.
27    Valid form is XXXXX where X represents integer.
28    """
29
30    default_error_messages = {
31        'invalid': _(u'Enter a postal code in the format XXXXX'),
32    }
33
34    def __init__(self, *args, **kwargs):
35        super(ILPostalCodeField, self).__init__(r'^\d{5}$', *args, **kwargs)
36
37    def clean(self, value):
38        if value not in EMPTY_VALUES:
39            value = value.replace(" ", "")
40        return super(ILPostalCodeField, self).clean(value)
41
42
43class ILIDNumberField(Field):
44    """
45    A form field that validates its input as an Israeli identification number.
46    Valid form is per the Israeli ID specification.
47    """
48
49    default_error_messages = {
50        'invalid': _(u'Enter a valid ID number.'),
51    }
52
53    def clean(self, value):
54        value = super(ILIDNumberField, self).clean(value)
55
56        if value in EMPTY_VALUES:
57            return u''
58
59        match = id_number_re.match(value)
60        if not match:
61            raise ValidationError(self.error_messages['invalid'])
62
63        value = match.group('number') + match.group('check')
64        if not luhn(value):
65            raise ValidationError(self.error_messages['invalid'])
66        return value