fields to the Brazilian localflavor. Thanks, onaiort@gmail.com and danielvaz@gmail.com. git-svn-id: http://code.djangoproject.com/svn/django/trunk@5089 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
b24c860fa2
commit
6c02565e4f
1
AUTHORS
1
AUTHORS
|
@ -168,6 +168,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
Sam Newman <http://www.magpiebrain.com/>
|
Sam Newman <http://www.magpiebrain.com/>
|
||||||
Neal Norwitz <nnorwitz@google.com>
|
Neal Norwitz <nnorwitz@google.com>
|
||||||
oggie rob <oz.robharvey@gmail.com>
|
oggie rob <oz.robharvey@gmail.com>
|
||||||
|
onaiort@gmail.com
|
||||||
Jay Parlar <parlar@gmail.com>
|
Jay Parlar <parlar@gmail.com>
|
||||||
pavithran s <pavithran.s@gmail.com>
|
pavithran s <pavithran.s@gmail.com>
|
||||||
Barry Pederson <bp@barryp.org>
|
Barry Pederson <bp@barryp.org>
|
||||||
|
|
|
@ -4,7 +4,7 @@ BR-specific Form helpers
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.newforms import ValidationError
|
from django.newforms import ValidationError
|
||||||
from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
|
from django.newforms.fields import Field, RegexField, CharField, Select, EMPTY_VALUES
|
||||||
from django.utils.encoding import smart_unicode
|
from django.utils.encoding import smart_unicode
|
||||||
from django.utils.translation import gettext
|
from django.utils.translation import gettext
|
||||||
import re
|
import re
|
||||||
|
@ -15,7 +15,7 @@ class BRZipCodeField(RegexField):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$',
|
super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$',
|
||||||
max_length=None, min_length=None,
|
max_length=None, min_length=None,
|
||||||
error_message=gettext(u'Enter a zip code in the format XXXXX-XXX.'),
|
error_message=gettext('Enter a zip code in the format XXXXX-XXX.'),
|
||||||
*args, **kwargs)
|
*args, **kwargs)
|
||||||
|
|
||||||
class BRPhoneNumberField(Field):
|
class BRPhoneNumberField(Field):
|
||||||
|
@ -37,3 +37,83 @@ class BRStateSelect(Select):
|
||||||
def __init__(self, attrs=None):
|
def __init__(self, attrs=None):
|
||||||
from br_states import STATE_CHOICES # relative import
|
from br_states import STATE_CHOICES # relative import
|
||||||
super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
|
super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
|
||||||
|
|
||||||
|
|
||||||
|
def DV_maker(v):
|
||||||
|
if v >= 2:
|
||||||
|
return 11 - v
|
||||||
|
return 0
|
||||||
|
|
||||||
|
class BRCPFField(CharField):
|
||||||
|
"""
|
||||||
|
This field validate a CPF number or a CPF string. A CPF number is
|
||||||
|
compounded by XXX.XXX.XXX-VD, the two last digits are check digits.
|
||||||
|
|
||||||
|
More information:
|
||||||
|
http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(BRCPFField, self).__init__(max_length=14, min_length=11, *args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
"""
|
||||||
|
Value can be either a string in the format XXX.XXX.XXX-XX or an
|
||||||
|
11-digit number.
|
||||||
|
"""
|
||||||
|
value = super(BRCPFField, self).clean(value)
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
return u''
|
||||||
|
orig_value = value[:]
|
||||||
|
if not value.isdigit():
|
||||||
|
value = re.sub("[-\.]", "", value)
|
||||||
|
try:
|
||||||
|
int(value)
|
||||||
|
except ValueError:
|
||||||
|
raise ValidationError(gettext("This field requires only numbers"))
|
||||||
|
if len(value) != 11:
|
||||||
|
raise ValidationError(gettext("This field requires at most 11 digits or 14 characters."))
|
||||||
|
orig_dv = value[-2:]
|
||||||
|
|
||||||
|
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(10, 1, -1))])
|
||||||
|
new_1dv = DV_maker(new_1dv % 11)
|
||||||
|
value = value[:-2] + str(new_1dv) + value[-1]
|
||||||
|
new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(11, 1, -1))])
|
||||||
|
new_2dv = DV_maker(new_2dv % 11)
|
||||||
|
value = value[:-1] + str(new_2dv)
|
||||||
|
if value[-2:] != orig_dv:
|
||||||
|
raise ValidationError(gettext("Invalid CPF number."))
|
||||||
|
|
||||||
|
return orig_value
|
||||||
|
|
||||||
|
class BRCNPJField(Field):
|
||||||
|
def clean(self, value):
|
||||||
|
"""
|
||||||
|
Value can be either a string in the format XX.XXX.XXX/XXXX-XX or a
|
||||||
|
group of 14 characters.
|
||||||
|
"""
|
||||||
|
value = super(BRCNPJField, self).clean(value)
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
return u''
|
||||||
|
orig_value = value[:]
|
||||||
|
if not value.isdigit():
|
||||||
|
value = re.sub("[-/\.]", "", value)
|
||||||
|
try:
|
||||||
|
int(value)
|
||||||
|
except ValueError:
|
||||||
|
raise ValidationError("This field requires only numbers")
|
||||||
|
if len(value) != 14:
|
||||||
|
raise ValidationError(
|
||||||
|
gettext("This field requires at least 14 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))])
|
||||||
|
new_1dv = DV_maker(new_1dv % 11)
|
||||||
|
value = value[:-2] + str(new_1dv) + value[-1]
|
||||||
|
new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(6, 1, -1) + range(9, 1, -1))])
|
||||||
|
new_2dv = DV_maker(new_2dv % 11)
|
||||||
|
value = value[:-1] + str(new_2dv)
|
||||||
|
if value[-2:] != orig_dv:
|
||||||
|
raise ValidationError(gettext("Invalid CNPJ number"))
|
||||||
|
|
||||||
|
return orig_value
|
||||||
|
|
||||||
|
|
|
@ -840,6 +840,40 @@ ValidationError: [u'Enter a zip code in the format XXXXX-XXX.']
|
||||||
>>> f.clean('12345-123')
|
>>> f.clean('12345-123')
|
||||||
u'12345-123'
|
u'12345-123'
|
||||||
|
|
||||||
|
# BRCNPJField ############################################################
|
||||||
|
|
||||||
|
>>> from django.contrib.localflavor.br.forms import BRCNPJField
|
||||||
|
>>> f = BRCNPJField(required=True)
|
||||||
|
>>> f.clean('')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'This field is required.']
|
||||||
|
>>> f.clean('12-345-678/9012-10')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'Invalid CNPJ number']
|
||||||
|
>>> f.clean('12.345.678/9012-10')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'Invalid CNPJ number']
|
||||||
|
>>> f.clean('12345678/9012-10')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'Invalid CNPJ number']
|
||||||
|
>>> f.clean('64.132.916/0001-88')
|
||||||
|
'64.132.916/0001-88'
|
||||||
|
>>> f.clean('64-132-916/0001-88')
|
||||||
|
'64-132-916/0001-88'
|
||||||
|
>>> f.clean('64132916/0001-88')
|
||||||
|
'64132916/0001-88'
|
||||||
|
>>> f.clean('64.132.916/0001-XX')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'This field requires only numbers']
|
||||||
|
>>> f = BRCNPJField(required=False)
|
||||||
|
>>> f.clean('')
|
||||||
|
u''
|
||||||
|
|
||||||
# BRPhoneNumberField #########################################################
|
# BRPhoneNumberField #########################################################
|
||||||
|
|
||||||
>>> from django.contrib.localflavor.br.forms import BRPhoneNumberField
|
>>> from django.contrib.localflavor.br.forms import BRPhoneNumberField
|
||||||
|
|
Loading…
Reference in New Issue