Fixed #5871 -- Factored out the validation errors in localflavor form fields. Brings them into line with the standard newforms fields. Patch from Jan Rademaker.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@6926 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
4d7aa81a70
commit
1fcb4e4bcd
|
@ -24,18 +24,20 @@ class ARPostalCodeField(RegexField):
|
|||
|
||||
See http://www.correoargentino.com.ar/consulta_cpa/home.php
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext("Enter a postal code in the format NNNN or ANNNNAAA."),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ARPostalCodeField, self).__init__(r'^\d{4}$|^[A-HJ-NP-Za-hj-np-z]\d{4}\D{3}$',
|
||||
min_length=4, max_length=8,
|
||||
error_message=ugettext("Enter a postal code in the format NNNN or ANNNNAAA."),
|
||||
*args, **kwargs)
|
||||
min_length=4, max_length=8, *args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
value = super(ARPostalCodeField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
if len(value) not in (4, 8):
|
||||
raise ValidationError(ugettext("Enter a postal code in the format NNNN or ANNNNAAA."))
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
if len(value) == 8:
|
||||
return u'%s%s%s' % (value[0].upper(), value[1:5], value[5:].upper())
|
||||
return value
|
||||
|
@ -44,6 +46,11 @@ class ARDNIField(CharField):
|
|||
"""
|
||||
A field that validates `Documento Nacional de Identidad´ (DNI) numbers.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext("This field requires only numbers."),
|
||||
'max_digits': ugettext("This field requires 7 or 8 digits."),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ARDNIField, self).__init__(max_length=10, min_length=7, *args,
|
||||
**kwargs)
|
||||
|
@ -58,10 +65,9 @@ class ARDNIField(CharField):
|
|||
if not value.isdigit():
|
||||
value = value.replace('.', '')
|
||||
if not value.isdigit():
|
||||
raise ValidationError(ugettext("This field requires only numbers."))
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
if len(value) not in (7, 8):
|
||||
raise ValidationError(
|
||||
ugettext("This field requires 7 or 8 digits."))
|
||||
raise ValidationError(self.error_messages['max_digits'])
|
||||
|
||||
return value
|
||||
|
||||
|
@ -70,9 +76,13 @@ class ARCUITField(RegexField):
|
|||
This field validates a CUIT (Código Único de Identificación Tributaria). A
|
||||
CUIT is of the form XX-XXXXXXXX-V. The last digit is a check digit.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.'),
|
||||
'checksum': ugettext("Invalid CUIT."),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ARCUITField, self).__init__(r'^\d{2}-?\d{8}-?\d$',
|
||||
error_message=ugettext('Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.'),
|
||||
*args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
|
@ -85,7 +95,7 @@ class ARCUITField(RegexField):
|
|||
return u''
|
||||
value, cd = self._canon(value)
|
||||
if self._calc_cd(value) != cd:
|
||||
raise ValidationError(ugettext("Invalid CUIT."))
|
||||
raise ValidationError(self.error_messages['checksum'])
|
||||
return self._format(value, cd)
|
||||
|
||||
def _canon(self, cuit):
|
||||
|
|
|
@ -12,14 +12,20 @@ PHONE_DIGITS_RE = re.compile(r'^(\d{10})$')
|
|||
|
||||
class AUPostCodeField(RegexField):
|
||||
"""Australian post code field."""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a 4 digit post code.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(AUPostCodeField, self).__init__(r'^\d{4}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=ugettext('Enter a 4 digit post code.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class AUPhoneNumberField(Field):
|
||||
"""Australian phone number field."""
|
||||
default_error_messages = {
|
||||
'invalid': u'Phone numbers must contain 10 digits.',
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
"""
|
||||
Validate a phone number. Strips parentheses, whitespace and hyphens.
|
||||
|
@ -31,7 +37,7 @@ class AUPhoneNumberField(Field):
|
|||
phone_match = PHONE_DIGITS_RE.search(value)
|
||||
if phone_match:
|
||||
return u'%s' % phone_match.group(1)
|
||||
raise ValidationError(u'Phone numbers must contain 10 digits.')
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
class AUStateSelect(Select):
|
||||
"""
|
||||
|
|
|
@ -17,13 +17,19 @@ except NameError:
|
|||
phone_digits_re = re.compile(r'^(\d{2})[-\.]?(\d{4})[-\.]?(\d{4})$')
|
||||
|
||||
class BRZipCodeField(RegexField):
|
||||
default_error_messages = {
|
||||
'invalid': _('Enter a zip code in the format XXXXX-XXX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=_('Enter a zip code in the format XXXXX-XXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class BRPhoneNumberField(Field):
|
||||
default_error_messages = {
|
||||
'invalid': _('Phone numbers must be in XX-XXXX-XXXX format.'),
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
super(BRPhoneNumberField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
|
@ -32,7 +38,7 @@ class BRPhoneNumberField(Field):
|
|||
m = phone_digits_re.search(value)
|
||||
if m:
|
||||
return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
|
||||
raise ValidationError(_('Phone numbers must be in XX-XXXX-XXXX format.'))
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
class BRStateSelect(Select):
|
||||
"""
|
||||
|
@ -48,6 +54,9 @@ class BRStateChoiceField(Field):
|
|||
A choice field that uses a list of Brazilian states as its choices.
|
||||
"""
|
||||
widget = Select
|
||||
default_error_messages = {
|
||||
'invalid': _(u'Select a valid brazilian state. That state is not one of the available states.'),
|
||||
}
|
||||
|
||||
def __init__(self, required=True, widget=None, label=None,
|
||||
initial=None, help_text=None):
|
||||
|
@ -65,9 +74,7 @@ class BRStateChoiceField(Field):
|
|||
return value
|
||||
valid_values = set([smart_unicode(k) for k, v in self.widget.choices])
|
||||
if value not in valid_values:
|
||||
raise ValidationError(_(u'Select a valid brazilian state.'
|
||||
u' That state is not one'
|
||||
u' of the available states.'))
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
return value
|
||||
|
||||
def DV_maker(v):
|
||||
|
@ -83,6 +90,12 @@ class BRCPFField(CharField):
|
|||
More information:
|
||||
http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _("Invalid CPF number."),
|
||||
'max_digits': _("This field requires at most 11 digits or 14 characters."),
|
||||
'digits_only': _("This field requires only numbers."),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BRCPFField, self).__init__(max_length=14, min_length=11, *args, **kwargs)
|
||||
|
||||
|
@ -100,9 +113,9 @@ class BRCPFField(CharField):
|
|||
try:
|
||||
int(value)
|
||||
except ValueError:
|
||||
raise ValidationError(_("This field requires only numbers."))
|
||||
raise ValidationError(self.error_messages['digits_only'])
|
||||
if len(value) != 11:
|
||||
raise ValidationError(_("This field requires at most 11 digits or 14 characters."))
|
||||
raise ValidationError(self.error_messages['max_digits'])
|
||||
orig_dv = value[-2:]
|
||||
|
||||
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(10, 1, -1))])
|
||||
|
@ -112,11 +125,17 @@ class BRCPFField(CharField):
|
|||
new_2dv = DV_maker(new_2dv % 11)
|
||||
value = value[:-1] + str(new_2dv)
|
||||
if value[-2:] != orig_dv:
|
||||
raise ValidationError(_("Invalid CPF number."))
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
return orig_value
|
||||
|
||||
class BRCNPJField(Field):
|
||||
default_error_messages = {
|
||||
'invalid': _("Invalid CNPJ number."),
|
||||
'digits_only': _("This field requires only numbers."),
|
||||
'max_digits': _("This field requires at least 14 digits"),
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
"""
|
||||
Value can be either a string in the format XX.XXX.XXX/XXXX-XX or a
|
||||
|
@ -131,10 +150,9 @@ class BRCNPJField(Field):
|
|||
try:
|
||||
int(value)
|
||||
except ValueError:
|
||||
raise ValidationError("This field requires only numbers.")
|
||||
raise ValidationError(self.error_messages['digits_only'])
|
||||
if len(value) != 14:
|
||||
raise ValidationError(
|
||||
_("This field requires at least 14 digits"))
|
||||
raise ValidationError(self.error_messages['max_digits'])
|
||||
orig_dv = value[-2:]
|
||||
|
||||
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(5, 1, -1) + range(9, 1, -1))])
|
||||
|
@ -144,7 +162,6 @@ class BRCNPJField(Field):
|
|||
new_2dv = DV_maker(new_2dv % 11)
|
||||
value = value[:-1] + str(new_2dv)
|
||||
if value[-2:] != orig_dv:
|
||||
raise ValidationError(_("Invalid CNPJ number."))
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
return orig_value
|
||||
|
||||
|
|
|
@ -13,14 +13,20 @@ sin_re = re.compile(r"^(\d{3})-(\d{3})-(\d{3})$")
|
|||
|
||||
class CAPostalCodeField(RegexField):
|
||||
"""Canadian postal code field."""
|
||||
default_error_messages = {
|
||||
'invalid': gettext(u'Enter a postal code in the format XXX XXX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CAPostalCodeField, self).__init__(r'^[ABCEGHJKLMNPRSTVXYZ]\d[A-Z] \d[A-Z]\d$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=gettext(u'Enter a postal code in the format XXX XXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class CAPhoneNumberField(Field):
|
||||
"""Canadian phone number field."""
|
||||
default_error_messages = {
|
||||
'invalid': u'Phone numbers must be in XXX-XXX-XXXX format.',
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
"""Validate a phone number.
|
||||
"""
|
||||
|
@ -31,7 +37,7 @@ class CAPhoneNumberField(Field):
|
|||
m = phone_digits_re.search(value)
|
||||
if m:
|
||||
return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
|
||||
raise ValidationError(u'Phone numbers must be in XXX-XXX-XXXX format.')
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
class CAProvinceField(Field):
|
||||
"""
|
||||
|
@ -39,6 +45,10 @@ class CAProvinceField(Field):
|
|||
It normalizes the input to the standard two-leter postal service
|
||||
abbreviation for the given province.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': u'Enter a Canadian province or territory.',
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
from ca_provinces import PROVINCES_NORMALIZED
|
||||
super(CAProvinceField, self).clean(value)
|
||||
|
@ -53,7 +63,7 @@ class CAProvinceField(Field):
|
|||
return PROVINCES_NORMALIZED[value.strip().lower()].decode('ascii')
|
||||
except KeyError:
|
||||
pass
|
||||
raise ValidationError(u'Enter a Canadian province or territory.')
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
class CAProvinceSelect(Select):
|
||||
"""
|
||||
|
@ -74,19 +84,23 @@ class CASocialInsuranceNumberField(Field):
|
|||
* Passes the check digit process "Luhn Algorithm"
|
||||
See: http://en.wikipedia.org/wiki/Social_Insurance_Number
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.'),
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
super(CASocialInsuranceNumberField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
msg = ugettext('Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.')
|
||||
|
||||
match = re.match(sin_re, value)
|
||||
if not match:
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
number = u'%s-%s-%s' % (match.group(1), match.group(2), match.group(3))
|
||||
check_number = u'%s%s%s' % (match.group(1), match.group(2), match.group(3))
|
||||
if not self.luhn_checksum_is_valid(check_number):
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
return number
|
||||
|
||||
def luhn_checksum_is_valid(self, number):
|
||||
|
|
|
@ -12,11 +12,13 @@ id_re = re.compile(r"^(?P<idnumber>\w{8})(?P<pos9>(\d{1}|<))(?P<checksum>\d{1})$
|
|||
phone_digits_re = re.compile(r'^0([1-9]{1})\d{8}$')
|
||||
|
||||
class CHZipCodeField(RegexField):
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a zip code in the format XXXX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CHZipCodeField, self).__init__(r'^\d{4}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=ugettext('Enter a zip code in the format XXXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class CHPhoneNumberField(Field):
|
||||
"""
|
||||
|
@ -25,6 +27,10 @@ class CHPhoneNumberField(Field):
|
|||
'0XX.XXX.XX.XX' and '0XXXXXXXXX' validate but are corrected to
|
||||
'0XX XXX XX XX'.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': 'Phone numbers must be in 0XX XXX XX XX format.',
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
super(CHPhoneNumberField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
|
@ -33,7 +39,7 @@ class CHPhoneNumberField(Field):
|
|||
m = phone_digits_re.search(value)
|
||||
if m:
|
||||
return u'%s %s %s %s' % (value[0:3], value[3:6], value[6:8], value[8:10])
|
||||
raise ValidationError('Phone numbers must be in 0XX XXX XX XX format.')
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
class CHStateSelect(Select):
|
||||
"""
|
||||
|
@ -54,6 +60,10 @@ class CHIdentityCardNumberField(Field):
|
|||
|
||||
Algorithm is documented at http://adi.kousz.ch/artikel/IDCHE.htm
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format.'),
|
||||
}
|
||||
|
||||
def has_valid_checksum(self, number):
|
||||
given_number, given_checksum = number[:-1], number[-1]
|
||||
new_number = given_number
|
||||
|
@ -87,23 +97,22 @@ class CHIdentityCardNumberField(Field):
|
|||
|
||||
def clean(self, value):
|
||||
super(CHIdentityCardNumberField, self).clean(value)
|
||||
error_msg = ugettext('Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format.')
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
|
||||
match = re.match(id_re, value)
|
||||
if not match:
|
||||
raise ValidationError(error_msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
idnumber, pos9, checksum = match.groupdict()['idnumber'], match.groupdict()['pos9'], match.groupdict()['checksum']
|
||||
|
||||
if idnumber == '00000000' or \
|
||||
idnumber == 'A0000000':
|
||||
raise ValidationError(error_msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
all_digits = "%s%s%s" % (idnumber, pos9, checksum)
|
||||
if not self.has_valid_checksum(all_digits):
|
||||
raise ValidationError(error_msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
return u'%s%s%s' % (idnumber, pos9, checksum)
|
||||
|
||||
|
|
|
@ -25,16 +25,21 @@ class CLRutField(RegexField):
|
|||
Samples for testing are available from
|
||||
https://palena.sii.cl/cvc/dte/ee_empresas_emisoras.html
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a valid Chilean RUT.'),
|
||||
'strict': ugettext('Enter a valid Chilean RUT. The format is XX.XXX.XXX-X.'),
|
||||
'checksum': ugettext('The Chilean RUT is not valid.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
if 'strict' in kwargs:
|
||||
del kwargs['strict']
|
||||
super(CLRutField, self).__init__(r'^(\d{1,2}\.)?\d{3}\.\d{3}-[\dkK]$',
|
||||
error_message=ugettext('Enter valid a Chilean RUT. The format is XX.XXX.XXX-X.'),
|
||||
*args, **kwargs)
|
||||
error_message=self.default_error_messages['strict'], *args, **kwargs)
|
||||
else:
|
||||
# In non-strict mode, accept RUTs that validate but do not exist in
|
||||
# the real world.
|
||||
super(CLRutField, self).__init__(r'^[\d\.]{1,11}-?[\dkK]$', error_message=ugettext('Enter valid a Chilean RUT'), *args, **kwargs)
|
||||
super(CLRutField, self).__init__(r'^[\d\.]{1,11}-?[\dkK]$', *args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
"""
|
||||
|
@ -47,7 +52,7 @@ class CLRutField(RegexField):
|
|||
if self._algorithm(rut) == verificador:
|
||||
return self._format(rut, verificador)
|
||||
else:
|
||||
raise ValidationError(u'The Chilean RUT is not valid.')
|
||||
raise ValidationError(self.error_messages['checksum'])
|
||||
|
||||
def _algorithm(self, rut):
|
||||
"""
|
||||
|
|
|
@ -10,11 +10,12 @@ import re
|
|||
id_re = re.compile(r"^(?P<residence>\d{10})(?P<origin>\w{1,3})[-\ ]?(?P<birthday>\d{7})[-\ ]?(?P<validity>\d{7})[-\ ]?(?P<checksum>\d{1})$")
|
||||
|
||||
class DEZipCodeField(RegexField):
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a zip code in the format XXXXX.'),
|
||||
}
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DEZipCodeField, self).__init__(r'^\d{5}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=ugettext('Enter a zip code in the format XXXXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class DEStateSelect(Select):
|
||||
"""
|
||||
|
@ -36,6 +37,10 @@ class DEIdentityCardNumberField(Field):
|
|||
|
||||
Algorithm is documented at http://de.wikipedia.org/wiki/Personalausweis
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format.'),
|
||||
}
|
||||
|
||||
def has_valid_checksum(self, number):
|
||||
given_number, given_checksum = number[:-1], number[-1]
|
||||
calculated_checksum = 0
|
||||
|
@ -57,23 +62,22 @@ class DEIdentityCardNumberField(Field):
|
|||
|
||||
def clean(self, value):
|
||||
super(DEIdentityCardNumberField, self).clean(value)
|
||||
error_msg = ugettext('Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format.')
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
match = re.match(id_re, value)
|
||||
if not match:
|
||||
raise ValidationError(error_msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
gd = match.groupdict()
|
||||
residence, origin = gd['residence'], gd['origin']
|
||||
birthday, validity, checksum = gd['birthday'], gd['validity'], gd['checksum']
|
||||
|
||||
if residence == '0000000000' or birthday == '0000000' or validity == '0000000':
|
||||
raise ValidationError(error_msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
all_digits = u"%s%s%s%s" % (residence, birthday, validity, checksum)
|
||||
if not self.has_valid_checksum(residence) or not self.has_valid_checksum(birthday) or \
|
||||
not self.has_valid_checksum(validity) or not self.has_valid_checksum(all_digits):
|
||||
raise ValidationError(error_msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
return u'%s%s-%s-%s-%s' % (residence, origin, birthday, validity, checksum)
|
||||
|
|
|
@ -15,12 +15,14 @@ class ESPostalCodeField(RegexField):
|
|||
Spanish postal code is a five digits string, with two first digits
|
||||
between 01 and 52, assigned to provinces code.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _('Enter a valid postal code in the range and format 01XXX - 52XXX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ESPostalCodeField, self).__init__(
|
||||
r'^(0[1-9]|[1-4][0-9]|5[0-2])\d{3}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=_('Enter a valid postal code in the range and format 01XXX - 52XXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class ESPhoneNumberField(RegexField):
|
||||
"""
|
||||
|
@ -33,11 +35,13 @@ class ESPhoneNumberField(RegexField):
|
|||
|
||||
TODO: accept and strip characters like dot, hyphen... in phone number
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _('Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ESPhoneNumberField, self).__init__(r'^(6|8|9)\d{8}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=_('Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class ESIdentityCardNumberField(RegexField):
|
||||
"""
|
||||
|
@ -58,19 +62,23 @@ class ESIdentityCardNumberField(RegexField):
|
|||
public, and different authors have different opinions on which ones allows
|
||||
letters, so both validations are assumed true for all types.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _('Please enter a valid NIF, NIE, or CIF.'),
|
||||
'invalid_only_nif': _('Please enter a valid NIF or NIE.'),
|
||||
'invalid_nif': _('Invalid checksum for NIF.'),
|
||||
'invalid_nie': _('Invalid checksum for NIE.'),
|
||||
'invalid_cif': _('Invalid checksum for CIF.'),
|
||||
}
|
||||
|
||||
def __init__(self, only_nif=False, *args, **kwargs):
|
||||
self.only_nif = only_nif
|
||||
self.nif_control = 'TRWAGMYFPDXBNJZSQVHLCKE'
|
||||
self.cif_control = 'JABCDEFGHI'
|
||||
self.cif_types = 'ABCDEFGHKLMNPQS'
|
||||
self.nie_types = 'XT'
|
||||
if self.only_nif:
|
||||
self.id_types = 'NIF or NIE'
|
||||
else:
|
||||
self.id_types = 'NIF, NIE, or CIF'
|
||||
super(ESIdentityCardNumberField, self).__init__(r'^([%s]?)[ -]?(\d+)[ -]?([%s]?)$' % (self.cif_types + self.nie_types + self.cif_types.lower() + self.nie_types.lower(), self.nif_control + self.nif_control.lower()),
|
||||
max_length=None, min_length=None,
|
||||
error_message=_('Please enter a valid %s.' % self.id_types),
|
||||
error_message=self.default_error_messages['invalid%s' % (self.only_nif and '_only_nif' or '')],
|
||||
*args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
|
@ -88,13 +96,13 @@ class ESIdentityCardNumberField(RegexField):
|
|||
if letter2 == nif_get_checksum(number):
|
||||
return value
|
||||
else:
|
||||
raise ValidationError, _('Invalid checksum for NIF.')
|
||||
raise ValidationError, self.error_messages['invalid_nif']
|
||||
elif letter1 in self.nie_types and letter2:
|
||||
# NIE
|
||||
if letter2 == nif_get_checksum(number):
|
||||
return value
|
||||
else:
|
||||
raise ValidationError, _('Invalid checksum for NIE.')
|
||||
raise ValidationError, self.error_messages['invalid_nie']
|
||||
elif not self.only_nif and letter1 in self.cif_types and len(number) in [7, 8]:
|
||||
# CIF
|
||||
if not letter2:
|
||||
|
@ -103,9 +111,9 @@ class ESIdentityCardNumberField(RegexField):
|
|||
if letter2 in [checksum, self.cif_control[checksum]]:
|
||||
return value
|
||||
else:
|
||||
raise ValidationError, _('Invalid checksum for CIF.')
|
||||
raise ValidationError, self.error_messages['invalid_cif']
|
||||
else:
|
||||
raise ValidationError, _('Please enter a valid %s.' % self.id_types)
|
||||
raise ValidationError, self.error_messages['invalid']
|
||||
|
||||
class ESCCCField(RegexField):
|
||||
"""
|
||||
|
@ -130,11 +138,14 @@ class ESCCCField(RegexField):
|
|||
|
||||
TODO: allow IBAN validation too
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _('Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX.'),
|
||||
'checksum': _('Invalid checksum for bank account number.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ESCCCField, self).__init__(r'^\d{4}[ -]?\d{4}[ -]?\d{2}[ -]?\d{10}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=_('Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
super(ESCCCField, self).clean(value)
|
||||
|
@ -147,7 +158,7 @@ class ESCCCField(RegexField):
|
|||
if get_checksum('00' + entity + office) + get_checksum(account) == checksum:
|
||||
return value
|
||||
else:
|
||||
raise ValidationError, _('Invalid checksum for bank account number.')
|
||||
raise ValidationError, self.error_messages['checksum']
|
||||
|
||||
class ESRegionSelect(Select):
|
||||
"""
|
||||
|
|
|
@ -8,11 +8,12 @@ from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
|
|||
from django.utils.translation import ugettext
|
||||
|
||||
class FIZipCodeField(RegexField):
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a zip code in the format XXXXX.'),
|
||||
}
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(FIZipCodeField, self).__init__(r'^\d{5}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=ugettext('Enter a zip code in the format XXXXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class FIMunicipalitySelect(Select):
|
||||
"""
|
||||
|
@ -23,6 +24,10 @@ class FIMunicipalitySelect(Select):
|
|||
super(FIMunicipalitySelect, self).__init__(attrs, choices=MUNICIPALITY_CHOICES)
|
||||
|
||||
class FISocialSecurityNumber(Field):
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a valid Finnish social security number.'),
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
super(FISocialSecurityNumber, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
|
@ -37,9 +42,9 @@ class FISocialSecurityNumber(Field):
|
|||
(?P<serial>(\d{3}))
|
||||
(?P<checksum>[%s])$""" % checkmarks, value, re.VERBOSE | re.IGNORECASE)
|
||||
if not result:
|
||||
raise ValidationError(ugettext('Enter a valid Finnish social security number.'))
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
gd = result.groupdict()
|
||||
checksum = int(gd['date'] + gd['serial'])
|
||||
if checkmarks[checksum % len(checkmarks)] == gd['checksum'].upper():
|
||||
return u'%s' % value.upper()
|
||||
raise ValidationError(ugettext('Enter a valid Finnish social security number.'))
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
|
|
@ -11,11 +11,13 @@ import re
|
|||
phone_digits_re = re.compile(r'^0\d(\s|\.)?(\d{2}(\s|\.)?){3}\d{2}$')
|
||||
|
||||
class FRZipCodeField(RegexField):
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a zip code in the format XXXXX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(FRZipCodeField, self).__init__(r'^\d{5}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=ugettext('Enter a zip code in the format XXXXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class FRPhoneNumberField(Field):
|
||||
"""
|
||||
|
@ -24,6 +26,10 @@ class FRPhoneNumberField(Field):
|
|||
'0X.XX.XX.XX.XX' and '0XXXXXXXXX' validate but are corrected to
|
||||
'0X XX XX XX XX'.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': u'Phone numbers must be in 0X XX XX XX XX format.',
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
super(FRPhoneNumberField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
|
@ -32,7 +38,7 @@ class FRPhoneNumberField(Field):
|
|||
m = phone_digits_re.search(value)
|
||||
if m:
|
||||
return u'%s %s %s %s %s' % (value[0:2], value[2:4], value[4:6], value[6:8], value[8:10])
|
||||
raise ValidationError(u'Phone numbers must be in 0X XX XX XX XX format.')
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
class FRDepartmentSelect(Select):
|
||||
"""
|
||||
|
|
|
@ -10,11 +10,13 @@ import re
|
|||
|
||||
|
||||
class INZipCodeField(RegexField):
|
||||
default_error_messages = {
|
||||
'invalid': gettext(u'Enter a zip code in the format XXXXXXX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(INZipCodeField, self).__init__(r'^\d{6}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=gettext(u'Enter a zip code in the format XXXXXXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class INStateField(Field):
|
||||
"""
|
||||
|
@ -22,6 +24,10 @@ class INStateField(Field):
|
|||
abbreviation. It normalizes the input to the standard two-letter vehicle
|
||||
registration abbreviation for the given state or union territory
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': u'Enter a Indian state or territory.',
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
from in_states import STATES_NORMALIZED
|
||||
super(INStateField, self).clean(value)
|
||||
|
@ -36,7 +42,7 @@ class INStateField(Field):
|
|||
return smart_unicode(STATES_NORMALIZED[value.strip().lower()])
|
||||
except KeyError:
|
||||
pass
|
||||
raise ValidationError(u'Enter a Indian state or territory.')
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
class INStateSelect(Select):
|
||||
"""
|
||||
|
|
|
@ -13,10 +13,14 @@ class ISIdNumberField(RegexField):
|
|||
Icelandic identification number (kennitala). This is a number every citizen
|
||||
of Iceland has.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a valid Icelandic identification number. The format is XXXXXX-XXXX.'),
|
||||
'checksum': ugettext(u'The Icelandic identification number is not valid.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
error_msg = ugettext('Enter a valid Icelandic identification number. The format is XXXXXX-XXXX.')
|
||||
kwargs['min_length'],kwargs['max_length'] = 10,11
|
||||
super(ISIdNumberField, self).__init__(r'^\d{6}(-| )?\d{4}$', error_message=error_msg, *args, **kwargs)
|
||||
super(ISIdNumberField, self).__init__(r'^\d{6}(-| )?\d{4}$', *args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
value = super(ISIdNumberField, self).clean(value)
|
||||
|
@ -28,7 +32,7 @@ class ISIdNumberField(RegexField):
|
|||
if self._validate(value):
|
||||
return self._format(value)
|
||||
else:
|
||||
raise ValidationError(ugettext(u'The Icelandic identification number is not valid.'))
|
||||
raise ValidationError(self.error_messages['checksum'])
|
||||
|
||||
def _canonify(self, value):
|
||||
"""
|
||||
|
|
|
@ -10,11 +10,12 @@ from django.contrib.localflavor.it.util import ssn_check_digit, vat_number_check
|
|||
import re
|
||||
|
||||
class ITZipCodeField(RegexField):
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a valid zip code.'),
|
||||
}
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ITZipCodeField, self).__init__(r'^\d{5}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=ugettext('Enter a valid zip code.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class ITRegionSelect(Select):
|
||||
"""
|
||||
|
@ -38,11 +39,13 @@ class ITSocialSecurityNumberField(RegexField):
|
|||
For reference see http://www.agenziaentrate.it/ and search for
|
||||
'Informazioni sulla codificazione delle persone fisiche'.
|
||||
"""
|
||||
err_msg = ugettext(u'Enter a valid Social Security number.')
|
||||
default_error_messages = {
|
||||
'invalid': ugettext(u'Enter a valid Social Security number.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ITSocialSecurityNumberField, self).__init__(r'^\w{3}\s*\w{3}\s*\w{5}\s*\w{5}$',
|
||||
max_length=None, min_length=None, error_message=self.err_msg,
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
value = super(ITSocialSecurityNumberField, self).clean(value)
|
||||
|
@ -52,26 +55,29 @@ class ITSocialSecurityNumberField(RegexField):
|
|||
try:
|
||||
check_digit = ssn_check_digit(value)
|
||||
except ValueError:
|
||||
raise ValidationError(self.err_msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
if not value[15] == check_digit:
|
||||
raise ValidationError(self.err_msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
return value
|
||||
|
||||
class ITVatNumberField(Field):
|
||||
"""
|
||||
A form field that validates Italian VAT numbers (partita IVA).
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext(u'Enter a valid VAT number.'),
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
value = super(ITVatNumberField, self).clean(value)
|
||||
if value == u'':
|
||||
return value
|
||||
err_msg = ugettext(u'Enter a valid VAT number.')
|
||||
try:
|
||||
vat_number = int(value)
|
||||
except ValueError:
|
||||
raise ValidationError(err_msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
vat_number = str(vat_number).zfill(11)
|
||||
check_digit = vat_number_check_digit(vat_number[0:10])
|
||||
if not vat_number[10] == check_digit:
|
||||
raise ValidationError(err_msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
return smart_unicode(vat_number)
|
||||
|
|
|
@ -15,11 +15,13 @@ class JPPostalCodeField(RegexField):
|
|||
|
||||
Accepts 7 digits, with or without a hyphen.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a postal code in the format XXXXXXX or XXX-XXXX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(JPPostalCodeField, self).__init__(r'^\d{3}-\d{4}$|^\d{7}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=ugettext('Enter a postal code in the format XXXXXXX or XXX-XXXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
"""
|
||||
|
|
|
@ -17,18 +17,21 @@ class NLZipCodeField(Field):
|
|||
"""
|
||||
A Dutch postal code field.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _('Enter a valid postal code'),
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
super(NLZipCodeField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
|
||||
msg = _('Enter a valid postal code')
|
||||
value = value.strip().upper().replace(' ', '')
|
||||
if not pc_re.search(value):
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
if int(value[:4]) < 1000:
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
return u'%s %s' % (value[:4], value[4:])
|
||||
|
||||
|
@ -45,12 +48,15 @@ class NLPhoneNumberField(Field):
|
|||
"""
|
||||
A Dutch telephone number field.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _('Enter a valid phone number'),
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
super(NLPhoneNumberField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
|
||||
msg = _('Enter a valid phone number')
|
||||
phone_nr = re.sub('[\-\s\(\)]', '', smart_unicode(value))
|
||||
|
||||
if len(phone_nr) == 10 and numeric_re.search(phone_nr):
|
||||
|
@ -60,7 +66,7 @@ class NLPhoneNumberField(Field):
|
|||
numeric_re.search(phone_nr[3:]):
|
||||
return value
|
||||
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
class NLSoFiNumberField(Field):
|
||||
"""
|
||||
|
@ -68,18 +74,20 @@ class NLSoFiNumberField(Field):
|
|||
|
||||
http://nl.wikipedia.org/wiki/Sofinummer
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _('Enter a valid SoFi number'),
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
super(NLSoFiNumberField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
|
||||
msg = _('Enter a valid SoFi number')
|
||||
|
||||
if not sofi_re.search(value):
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
if int(value) == 0:
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
checksum = 0
|
||||
for i in range(9, 1, -1):
|
||||
|
@ -87,6 +95,6 @@ class NLSoFiNumberField(Field):
|
|||
checksum -= int(value[-1])
|
||||
|
||||
if checksum % 11 != 0:
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
return value
|
||||
|
|
|
@ -8,11 +8,13 @@ from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
|
|||
from django.utils.translation import ugettext
|
||||
|
||||
class NOZipCodeField(RegexField):
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a zip code in the format XXXX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NOZipCodeField, self).__init__(r'^\d{4}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=ugettext('Enter a zip code in the format XXXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class NOMunicipalitySelect(Select):
|
||||
"""
|
||||
|
@ -27,14 +29,17 @@ class NOSocialSecurityNumber(Field):
|
|||
"""
|
||||
Algorithm is documented at http://no.wikipedia.org/wiki/Personnummer
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext(u'Enter a valid Norwegian social security number.'),
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
super(NOSocialSecurityNumber, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
|
||||
msg = ugettext(u'Enter a valid Norwegian social security number.')
|
||||
if not re.match(r'^\d{11}$', value):
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
day = int(value[:2])
|
||||
month = int(value[2:4])
|
||||
|
@ -52,7 +57,7 @@ class NOSocialSecurityNumber(Field):
|
|||
if 900 <= inum < 1000 and year2 > 39:
|
||||
self.birthday = datetime.date(1900+year2, month, day)
|
||||
except ValueError:
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
sexnum = int(value[8])
|
||||
if sexnum % 2 == 0:
|
||||
|
@ -68,9 +73,9 @@ class NOSocialSecurityNumber(Field):
|
|||
return sum([(a * b) for (a, b) in zip(aval, bval)])
|
||||
|
||||
if multiply_reduce(digits, weight_1) % 11 != 0:
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
if multiply_reduce(digits, weight_2) % 11 != 0:
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
return value
|
||||
|
||||
|
|
|
@ -19,6 +19,11 @@ class PEDNIField(CharField):
|
|||
"""
|
||||
A field that validates `Documento Nacional de IdentidadŽ (DNI) numbers.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext("This field requires only numbers."),
|
||||
'max_digits': ugettext("This field requires 8 digits."),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PEDNIField, self).__init__(max_length=8, min_length=8, *args,
|
||||
**kwargs)
|
||||
|
@ -31,9 +36,9 @@ class PEDNIField(CharField):
|
|||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
if not value.isdigit():
|
||||
raise ValidationError(ugettext("This field requires only numbers."))
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
if len(value) != 8:
|
||||
raise ValidationError(ugettext("This field requires 8 digits."))
|
||||
raise ValidationError(self.error_messages['max_digits'])
|
||||
|
||||
return value
|
||||
|
||||
|
@ -42,6 +47,11 @@ class PERUCField(RegexField):
|
|||
This field validates a RUC (Registro Unico de Contribuyentes). A RUC is of
|
||||
the form XXXXXXXXXXX.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext("This field requires only numbers."),
|
||||
'max_digits': ugettext("This field requires 11 digits."),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PERUCField, self).__init__(max_length=11, min_length=11, *args,
|
||||
**kwargs)
|
||||
|
@ -54,8 +64,8 @@ class PERUCField(RegexField):
|
|||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
if not value.isdigit():
|
||||
raise ValidationError(ugettext("This field requires only numbers."))
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
if len(value) != 11:
|
||||
raise ValidationError(ugettext("This field requires 11 digits."))
|
||||
raise ValidationError(self.error_messages['max_digits'])
|
||||
return value
|
||||
|
||||
|
|
|
@ -35,16 +35,19 @@ class PLNationalIdentificationNumberField(RegexField):
|
|||
|
||||
The algorithm is documented at http://en.wikipedia.org/wiki/PESEL.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _(u'National Identification Number consists of 11 digits.'),
|
||||
'checksum': _(u'Wrong checksum for the National Identification Number.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PLNationalIdentificationNumberField, self).__init__(r'^\d{11}$',
|
||||
max_length=None, min_length=None, error_message=_(u'National Identification Number consists of 11 digits.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
def clean(self,value):
|
||||
super(PLNationalIdentificationNumberField, self).clean(value)
|
||||
if not self.has_valid_checksum(value):
|
||||
raise ValidationError(_(u'Wrong checksum for the National Identification Number.'))
|
||||
raise ValidationError(self.error_messages['checksum'])
|
||||
return u'%s' % value
|
||||
|
||||
def has_valid_checksum(self, number):
|
||||
|
@ -65,17 +68,20 @@ class PLTaxNumberField(RegexField):
|
|||
Checksum algorithm based on documentation at
|
||||
http://wipos.p.lodz.pl/zylla/ut/nip-rego.html
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _(u'Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX.'),
|
||||
'checksum': _(u'Wrong checksum for the Tax Number (NIP).'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PLTaxNumberField, self).__init__(r'^\d{3}-\d{3}-\d{2}-\d{2}$|^\d{2}-\d{2}-\d{3}-\d{3}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=_(u'Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX.'), *args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
def clean(self,value):
|
||||
super(PLTaxNumberField, self).clean(value)
|
||||
value = re.sub("[-]", "", value)
|
||||
if not self.has_valid_checksum(value):
|
||||
raise ValidationError(_(u'Wrong checksum for the Tax Number (NIP).'))
|
||||
raise ValidationError(self.error_messages['checksum'])
|
||||
return u'%s' % value
|
||||
|
||||
def has_valid_checksum(self, number):
|
||||
|
@ -102,15 +108,19 @@ class PLNationalBusinessRegisterField(RegexField):
|
|||
|
||||
The checksum algorithm is documented at http://wipos.p.lodz.pl/zylla/ut/nip-rego.html
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _(u'National Business Register Number (REGON) consists of 7 or 9 digits.'),
|
||||
'checksum': _(u'Wrong checksum for the National Business Register Number (REGON).'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PLNationalBusinessRegisterField, self).__init__(r'^\d{7,9}$',
|
||||
max_length=None, min_length=None, error_message=_(u'National Business Register Number (REGON) consists of 7 or 9 digits.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
def clean(self,value):
|
||||
super(PLNationalBusinessRegisterField, self).clean(value)
|
||||
if not self.has_valid_checksum(value):
|
||||
raise ValidationError(_(u'Wrong checksum for the National Business Register Number (REGON).'))
|
||||
raise ValidationError(self.error_messages['checksum'])
|
||||
return u'%s' % value
|
||||
|
||||
def has_valid_checksum(self, number):
|
||||
|
@ -142,9 +152,10 @@ class PLPostalCodeField(RegexField):
|
|||
A form field that validates as Polish postal code.
|
||||
Valid code is XX-XXX where X is digit.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': _(u'Enter a postal code in the format XX-XXX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PLPostalCodeField, self).__init__(r'^\d{2}-\d{3}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=_(u'Enter a postal code in the format XX-XXX.'),
|
||||
*args, **kwargs)
|
||||
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
|
|
@ -26,11 +26,13 @@ class SKPostalCodeField(RegexField):
|
|||
A form field that validates its input as Slovak postal code.
|
||||
Valid form is XXXXX or XXX XX, where X represents integer.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext(u'Enter a postal code in the format XXXXX or XXX XX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SKPostalCodeField, self).__init__(r'^\d{5}$|^\d{3} \d{2}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=ugettext(u'Enter a postal code in the format XXXXX or XXX XX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
"""
|
||||
|
|
|
@ -12,11 +12,13 @@ class UKPostcodeField(RegexField):
|
|||
The regular expression used is sourced from the schema for British Standard
|
||||
BS7666 address types: http://www.govtalk.gov.uk/gdsc/schemas/bs7666-v2-0.xsd
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext(u'Enter a postcode. A space is required between the two postcode parts.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
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})$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=ugettext(u'Enter a postcode. A space is required between the two postcode parts.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class UKCountySelect(Select):
|
||||
"""
|
||||
|
|
|
@ -12,13 +12,19 @@ phone_digits_re = re.compile(r'^(?:1-?)?(\d{3})[-\.]?(\d{3})[-\.]?(\d{4})$')
|
|||
ssn_re = re.compile(r"^(?P<area>\d{3})[-\ ]?(?P<group>\d{2})[-\ ]?(?P<serial>\d{4})$")
|
||||
|
||||
class USZipCodeField(RegexField):
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a zip code in the format XXXXX or XXXXX-XXXX.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(USZipCodeField, self).__init__(r'^\d{5}(?:-\d{4})?$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=ugettext('Enter a zip code in the format XXXXX or XXXXX-XXXX.'),
|
||||
*args, **kwargs)
|
||||
max_length=None, min_length=None, *args, **kwargs)
|
||||
|
||||
class USPhoneNumberField(Field):
|
||||
default_error_messages = {
|
||||
'invalid': u'Phone numbers must be in XXX-XXX-XXXX format.',
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
super(USPhoneNumberField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
|
@ -27,7 +33,7 @@ class USPhoneNumberField(Field):
|
|||
m = phone_digits_re.search(value)
|
||||
if m:
|
||||
return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
|
||||
raise ValidationError(u'Phone numbers must be in XXX-XXX-XXXX format.')
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
class USSocialSecurityNumberField(Field):
|
||||
"""
|
||||
|
@ -44,28 +50,31 @@ class USSocialSecurityNumberField(Field):
|
|||
promotional use or distribution (e.g., the Woolworth's number or the
|
||||
1962 promotional number).
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext('Enter a valid U.S. Social Security number in XXX-XX-XXXX format.'),
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
super(USSocialSecurityNumberField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
msg = ugettext('Enter a valid U.S. Social Security number in XXX-XX-XXXX format.')
|
||||
match = re.match(ssn_re, value)
|
||||
if not match:
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
area, group, serial = match.groupdict()['area'], match.groupdict()['group'], match.groupdict()['serial']
|
||||
|
||||
# First pass: no blocks of all zeroes.
|
||||
if area == '000' or \
|
||||
group == '00' or \
|
||||
serial == '0000':
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
# Second pass: promotional and otherwise permanently invalid numbers.
|
||||
if area == '666' or \
|
||||
(area == '987' and group == '65' and 4320 <= int(serial) <= 4329) or \
|
||||
value == '078-05-1120' or \
|
||||
value == '219-09-9999':
|
||||
raise ValidationError(msg)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
return u'%s-%s-%s' % (area, group, serial)
|
||||
|
||||
class USStateField(Field):
|
||||
|
@ -74,6 +83,10 @@ class USStateField(Field):
|
|||
It normalizes the input to the standard two-leter postal service
|
||||
abbreviation for the given state.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': u'Enter a U.S. state or territory.',
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
from us_states import STATES_NORMALIZED
|
||||
super(USStateField, self).clean(value)
|
||||
|
@ -88,7 +101,7 @@ class USStateField(Field):
|
|||
return STATES_NORMALIZED[value.strip().lower()].decode('ascii')
|
||||
except KeyError:
|
||||
pass
|
||||
raise ValidationError(u'Enter a U.S. state or territory.')
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
class USStateSelect(Select):
|
||||
"""
|
||||
|
|
|
@ -16,10 +16,9 @@ class ZAIDField(Field):
|
|||
using the Luhn checksum, and uses a simlistic (read: not entirely accurate)
|
||||
check for the birthdate
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ZAIDField, self).__init__()
|
||||
self.error_message = _(u'Enter a valid South African ID number')
|
||||
default_error_messages = {
|
||||
'invalid': _(u'Enter a valid South African ID number'),
|
||||
}
|
||||
|
||||
def clean(self, value):
|
||||
# strip spaces and dashes
|
||||
|
@ -33,7 +32,7 @@ class ZAIDField(Field):
|
|||
match = re.match(id_re, value)
|
||||
|
||||
if not match:
|
||||
raise ValidationError(self.error_message)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
g = match.groupdict()
|
||||
|
||||
|
@ -43,15 +42,18 @@ class ZAIDField(Field):
|
|||
# There is no way to guess the century of a ZA ID number
|
||||
d = date(int(g['yy']) + 2000, int(g['mm']), int(g['dd']))
|
||||
except ValueError:
|
||||
raise ValidationError(self.error_message)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
if not luhn(value):
|
||||
raise ValidationError(self.error_message)
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
return value
|
||||
|
||||
class ZAPostCodeField(RegexField):
|
||||
default_error_messages = {
|
||||
'invalid': _(u'Enter a valid South African postal code'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ZAPostCodeField, self).__init__(r'^\d{4}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=_(u'Enter a valid South African postal code'))
|
||||
max_length=None, min_length=None)
|
||||
|
|
|
@ -41,7 +41,7 @@ Strict RUT usage (does not allow imposible values)
|
|||
>>> rut.clean('11-6')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'Enter valid a Chilean RUT. The format is XX.XXX.XXX-X.']
|
||||
ValidationError: [u'Enter a valid Chilean RUT. The format is XX.XXX.XXX-X.']
|
||||
|
||||
# valid format, bad verifier.
|
||||
>>> rut.clean('11.111.111-0')
|
||||
|
@ -53,17 +53,17 @@ ValidationError: [u'The Chilean RUT is not valid.']
|
|||
>>> rut.clean('767484100')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'Enter valid a Chilean RUT. The format is XX.XXX.XXX-X.']
|
||||
ValidationError: [u'Enter a valid Chilean RUT. The format is XX.XXX.XXX-X.']
|
||||
>>> rut.clean('78.412.790-7')
|
||||
u'78.412.790-7'
|
||||
>>> rut.clean('8.334.6043')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'Enter valid a Chilean RUT. The format is XX.XXX.XXX-X.']
|
||||
ValidationError: [u'Enter a valid Chilean RUT. The format is XX.XXX.XXX-X.']
|
||||
>>> rut.clean('76793310-K')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'Enter valid a Chilean RUT. The format is XX.XXX.XXX-X.']
|
||||
ValidationError: [u'Enter a valid Chilean RUT. The format is XX.XXX.XXX-X.']
|
||||
|
||||
## CLRegionSelect #########################################################
|
||||
>>> from django.contrib.localflavor.cl.forms import CLRegionSelect
|
||||
|
|
Loading…
Reference in New Issue