mirror of
https://github.com/django/django.git
synced 2025-07-04 09:49:12 +00:00
boulder-oracle-sprint: Merged to [5018]
git-svn-id: http://code.djangoproject.com/svn/django/branches/boulder-oracle-sprint@5019 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
e2a3b9e1bd
commit
ab622a35bd
1
AUTHORS
1
AUTHORS
@ -174,6 +174,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
J. Rademaker
|
||||
Michael Radziej <mir@noris.de>
|
||||
ramiro
|
||||
Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
|
||||
Brian Ray <http://brianray.chipy.org/>
|
||||
remco@diji.biz
|
||||
rhettg@gmail.com
|
||||
|
@ -3,12 +3,13 @@ These classes are light wrappers around Django's database API that provide
|
||||
convenience functionality and permalink functions for the databrowse app.
|
||||
"""
|
||||
|
||||
from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
|
||||
from django.db import models
|
||||
from django.utils import dateformat
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.translation import get_date_formats
|
||||
|
||||
EMPTY_VALUE = '(None)'
|
||||
|
||||
class EasyModel(object):
|
||||
def __init__(self, site, model):
|
||||
self.site = site
|
||||
@ -132,13 +133,16 @@ class EasyInstanceField(object):
|
||||
Returns a list of values for this field for this instance. It's a list
|
||||
so we can accomodate many-to-many fields.
|
||||
"""
|
||||
# This import is deliberately inside the function because it causes
|
||||
# some settings to be imported, and we don't want to do that at the
|
||||
# module level.
|
||||
if self.field.rel:
|
||||
if isinstance(self.field.rel, models.ManyToOneRel):
|
||||
objs = getattr(self.instance.instance, self.field.name)
|
||||
elif isinstance(self.field.rel, models.ManyToManyRel): # ManyToManyRel
|
||||
return list(getattr(self.instance.instance, self.field.name).all())
|
||||
elif self.field.choices:
|
||||
objs = dict(self.field.choices).get(self.raw_value, EMPTY_CHANGELIST_VALUE)
|
||||
objs = dict(self.field.choices).get(self.raw_value, EMPTY_VALUE)
|
||||
elif isinstance(self.field, models.DateField) or isinstance(self.field, models.TimeField):
|
||||
if self.raw_value:
|
||||
date_format, datetime_format, time_format = get_date_formats()
|
||||
@ -149,7 +153,7 @@ class EasyInstanceField(object):
|
||||
else:
|
||||
objs = capfirst(dateformat.format(self.raw_value, date_format))
|
||||
else:
|
||||
objs = EMPTY_CHANGELIST_VALUE
|
||||
objs = EMPTY_VALUE
|
||||
elif isinstance(self.field, models.BooleanField) or isinstance(self.field, models.NullBooleanField):
|
||||
objs = {True: 'Yes', False: 'No', None: 'Unknown'}[self.raw_value]
|
||||
else:
|
||||
|
@ -5,13 +5,15 @@ IT-specific Form helpers
|
||||
from django.newforms import ValidationError
|
||||
from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
|
||||
from django.utils.translation import gettext
|
||||
from django.utils.encoding import smart_unicode
|
||||
from django.contrib.localflavor.it.util import ssn_check_digit, vat_number_check_digit
|
||||
import re
|
||||
|
||||
class ITZipCodeField(RegexField):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ITZipCodeField, self).__init__(r'^\d{5}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=gettext(u'Enter a zip code in the format XXXXX.'),
|
||||
error_message=gettext(u'Enter a valid zip code.'),
|
||||
*args, **kwargs)
|
||||
|
||||
class ITRegionSelect(Select):
|
||||
@ -29,3 +31,47 @@ class ITProvinceSelect(Select):
|
||||
def __init__(self, attrs=None):
|
||||
from it_province import PROVINCE_CHOICES # relative import
|
||||
super(ITProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
|
||||
|
||||
class ITSocialSecurityNumberField(RegexField):
|
||||
"""
|
||||
A form field that validates Italian Social Security numbers (codice fiscale).
|
||||
For reference see http://www.agenziaentrate.it/ and search for
|
||||
'Informazioni sulla codificazione delle persone fisiche'.
|
||||
"""
|
||||
err_msg = gettext(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)
|
||||
|
||||
def clean(self, value):
|
||||
value = super(ITSocialSecurityNumberField, self).clean(value)
|
||||
if value == u'':
|
||||
return value
|
||||
value = re.sub('\s', u'', value).upper()
|
||||
try:
|
||||
check_digit = ssn_check_digit(value)
|
||||
except ValueError:
|
||||
raise ValidationError(self.err_msg)
|
||||
if not value[15] == check_digit:
|
||||
raise ValidationError(self.err_msg)
|
||||
return value
|
||||
|
||||
class ITVatNumberField(Field):
|
||||
"""
|
||||
A form field that validates Italian VAT numbers (partita IVA).
|
||||
"""
|
||||
def clean(self, value):
|
||||
value = super(ITVatNumberField, self).clean(value)
|
||||
if value == u'':
|
||||
return value
|
||||
err_msg = gettext(u'Enter a valid VAT number.')
|
||||
try:
|
||||
vat_number = int(value)
|
||||
except ValueError:
|
||||
raise ValidationError(err_msg)
|
||||
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)
|
||||
return smart_unicode(vat_number)
|
||||
|
40
django/contrib/localflavor/it/util.py
Normal file
40
django/contrib/localflavor/it/util.py
Normal file
@ -0,0 +1,40 @@
|
||||
def ssn_check_digit(value):
|
||||
"Calculate Italian social security number check digit."
|
||||
ssn_even_chars = {
|
||||
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
|
||||
'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9,
|
||||
'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16, 'R': 17, 'S': 18,
|
||||
'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24, 'Z': 25
|
||||
}
|
||||
ssn_odd_chars = {
|
||||
'0': 1, '1': 0, '2': 5, '3': 7, '4': 9, '5': 13, '6': 15, '7': 17, '8': 19, '9': 21,
|
||||
'A': 1, 'B': 0, 'C': 5, 'D': 7, 'E': 9, 'F': 13, 'G': 15, 'H': 17, 'I': 19, 'J': 21,
|
||||
'K': 2, 'L': 4, 'M': 18, 'N': 20, 'O': 11, 'P': 3, 'Q': 6, 'R': 8, 'S': 12,
|
||||
'T': 14, 'U': 16, 'V': 10, 'W': 22, 'X': 25, 'Y': 24, 'Z': 23
|
||||
}
|
||||
# Chars from 'A' to 'Z'
|
||||
ssn_check_digits = [chr(x) for x in range(65, 91)]
|
||||
|
||||
ssn = value.upper()
|
||||
total = 0
|
||||
for i in range(0,15):
|
||||
try:
|
||||
if i % 2 == 0:
|
||||
total += ssn_odd_chars[ssn[i]]
|
||||
else:
|
||||
total += ssn_even_chars[ssn[i]]
|
||||
except KeyError:
|
||||
msg = "Character '%(char)s' is not allowed." % {'char': ssn[i]}
|
||||
raise ValueError(msg)
|
||||
return ssn_check_digits[total % 26]
|
||||
|
||||
def vat_number_check_digit(vat_number):
|
||||
"Calculate Italian VAT number check digit."
|
||||
normalized_vat_number = str(vat_number).zfill(10)
|
||||
total = 0
|
||||
for i in range(0, 10, 2):
|
||||
total += int(normalized_vat_number[i])
|
||||
for i in range(1, 11, 2):
|
||||
quotient , remainder = divmod(int(normalized_vat_number[i]) * 2, 10)
|
||||
total += quotient + remainder
|
||||
return str((10 - total % 10) % 10)
|
@ -210,7 +210,7 @@ def get_sql_flush(style, tables, sequences):
|
||||
sql.append("%s %s %s %s %s %s;" % \
|
||||
(style.SQL_KEYWORD('ALTER'),
|
||||
style.SQL_KEYWORD('SEQUENCE'),
|
||||
style.SQL_FIELD('%s_%s_seq' % (table_name, column_name)),
|
||||
style.SQL_FIELD(quote_name('%s_%s_seq' % (table_name, column_name))),
|
||||
style.SQL_KEYWORD('RESTART'),
|
||||
style.SQL_KEYWORD('WITH'),
|
||||
style.SQL_FIELD('1')
|
||||
@ -221,7 +221,7 @@ def get_sql_flush(style, tables, sequences):
|
||||
sql.append("%s %s %s %s %s %s;" % \
|
||||
(style.SQL_KEYWORD('ALTER'),
|
||||
style.SQL_KEYWORD('SEQUENCE'),
|
||||
style.SQL_FIELD('%s_id_seq' % table_name),
|
||||
style.SQL_FIELD(quote_name('%s_id_seq' % table_name)),
|
||||
style.SQL_KEYWORD('RESTART'),
|
||||
style.SQL_KEYWORD('WITH'),
|
||||
style.SQL_FIELD('1')
|
||||
|
@ -167,7 +167,7 @@ def get_sql_flush(style, tables, sequences):
|
||||
sql.append("%s %s %s %s %s %s;" % \
|
||||
(style.SQL_KEYWORD('ALTER'),
|
||||
style.SQL_KEYWORD('SEQUENCE'),
|
||||
style.SQL_FIELD('%s_%s_seq' % (table_name, column_name)),
|
||||
style.SQL_FIELD(quote_name('%s_%s_seq' % (table_name, column_name))),
|
||||
style.SQL_KEYWORD('RESTART'),
|
||||
style.SQL_KEYWORD('WITH'),
|
||||
style.SQL_FIELD('1')
|
||||
@ -178,7 +178,7 @@ def get_sql_flush(style, tables, sequences):
|
||||
sql.append("%s %s %s %s %s %s;" % \
|
||||
(style.SQL_KEYWORD('ALTER'),
|
||||
style.SQL_KEYWORD('SEQUENCE'),
|
||||
style.SQL_FIELD('%s_id_seq' % table_name),
|
||||
style.SQL_FIELD(quote_name('%s_id_seq' % table_name)),
|
||||
style.SQL_KEYWORD('RESTART'),
|
||||
style.SQL_KEYWORD('WITH'),
|
||||
style.SQL_FIELD('1')
|
||||
|
@ -7,6 +7,13 @@ class Animal(models.Model):
|
||||
def __str__(self):
|
||||
return self.common_name
|
||||
|
||||
class Plant(models.Model):
|
||||
name = models.CharField(maxlength=150)
|
||||
|
||||
class Meta:
|
||||
# For testing when upper case letter in app name; regression for #4057
|
||||
db_table = "Fixtures_regress_plant"
|
||||
|
||||
__test__ = {'API_TESTS':"""
|
||||
>>> from django.core import management
|
||||
|
||||
|
@ -633,7 +633,7 @@ u'00100'
|
||||
>>> f.clean(' 00100')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'Enter a zip code in the format XXXXX.']
|
||||
ValidationError: [u'Enter a valid zip code.']
|
||||
|
||||
# ITRegionSelect #############################################################
|
||||
|
||||
@ -642,6 +642,46 @@ ValidationError: [u'Enter a zip code in the format XXXXX.']
|
||||
>>> w.render('regions', 'PMN')
|
||||
u'<select name="regions">\n<option value="ABR">Abruzzo</option>\n<option value="BAS">Basilicata</option>\n<option value="CAL">Calabria</option>\n<option value="CAM">Campania</option>\n<option value="EMR">Emilia-Romagna</option>\n<option value="FVG">Friuli-Venezia Giulia</option>\n<option value="LAZ">Lazio</option>\n<option value="LIG">Liguria</option>\n<option value="LOM">Lombardia</option>\n<option value="MAR">Marche</option>\n<option value="MOL">Molise</option>\n<option value="PMN" selected="selected">Piemonte</option>\n<option value="PUG">Puglia</option>\n<option value="SAR">Sardegna</option>\n<option value="SIC">Sicilia</option>\n<option value="TOS">Toscana</option>\n<option value="TAA">Trentino-Alto Adige</option>\n<option value="UMB">Umbria</option>\n<option value="VAO">Valle d\u2019Aosta</option>\n<option value="VEN">Veneto</option>\n</select>'
|
||||
|
||||
# ITSocialSecurityNumberField #################################################
|
||||
|
||||
>>> from django.contrib.localflavor.it.forms import ITSocialSecurityNumberField
|
||||
>>> f = ITSocialSecurityNumberField()
|
||||
>>> f.clean('LVSGDU99T71H501L')
|
||||
u'LVSGDU99T71H501L'
|
||||
>>> f.clean('LBRRME11A01L736W')
|
||||
u'LBRRME11A01L736W'
|
||||
>>> f.clean('lbrrme11a01l736w')
|
||||
u'LBRRME11A01L736W'
|
||||
>>> f.clean('LBR RME 11A01 L736W')
|
||||
u'LBRRME11A01L736W'
|
||||
>>> f.clean('LBRRME11A01L736A')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'Enter a valid Social Security number.']
|
||||
>>> f.clean('%BRRME11A01L736W')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'Enter a valid Social Security number.']
|
||||
|
||||
# ITVatNumberField ###########################################################
|
||||
|
||||
>>> from django.contrib.localflavor.it.forms import ITVatNumberField
|
||||
>>> f = ITVatNumberField()
|
||||
>>> f.clean('07973780013')
|
||||
u'07973780013'
|
||||
>>> f.clean('7973780013')
|
||||
u'07973780013'
|
||||
>>> f.clean(7973780013)
|
||||
u'07973780013'
|
||||
>>> f.clean('07973780014')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'Enter a valid VAT number.']
|
||||
>>> f.clean('A7973780013')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'Enter a valid VAT number.']
|
||||
|
||||
# FIZipCodeField #############################################################
|
||||
|
||||
FIZipCodeField validates that the data is a valid FI zipcode.
|
||||
|
Loading…
x
Reference in New Issue
Block a user