summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
Diffstat (limited to 'django')
-rw-r--r--django/contrib/databrowse/datastructures.py10
-rw-r--r--django/contrib/localflavor/it/forms.py48
-rw-r--r--django/contrib/localflavor/it/util.py40
-rw-r--r--django/db/backends/postgresql/base.py4
-rw-r--r--django/db/backends/postgresql_psycopg2/base.py4
5 files changed, 98 insertions, 8 deletions
diff --git a/django/contrib/databrowse/datastructures.py b/django/contrib/databrowse/datastructures.py
index 3c509a2830..24f2e68f46 100644
--- a/django/contrib/databrowse/datastructures.py
+++ b/django/contrib/databrowse/datastructures.py
@@ -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:
diff --git a/django/contrib/localflavor/it/forms.py b/django/contrib/localflavor/it/forms.py
index 8e9d8bc11d..bb1bb2e6a4 100644
--- a/django/contrib/localflavor/it/forms.py
+++ b/django/contrib/localflavor/it/forms.py
@@ -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)
diff --git a/django/contrib/localflavor/it/util.py b/django/contrib/localflavor/it/util.py
new file mode 100644
index 0000000000..49b607f160
--- /dev/null
+++ b/django/contrib/localflavor/it/util.py
@@ -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)
diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py
index 9f191f27a3..2f2363728f 100644
--- a/django/db/backends/postgresql/base.py
+++ b/django/db/backends/postgresql/base.py
@@ -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')
diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py
index 25dbd7873a..1a149f42a7 100644
--- a/django/db/backends/postgresql_psycopg2/base.py
+++ b/django/db/backends/postgresql_psycopg2/base.py
@@ -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')