diff --git a/trytond/ir/translation.xml b/trytond/ir/translation.xml
index 5c3f87decf..45bc5ad4b4 100644
--- a/trytond/ir/translation.xml
+++ b/trytond/ir/translation.xml
@@ -141,6 +141,16 @@ this repository contains the full copyright notices and license terms. -->
ir
+
+ selection_validation_record
+ en_US
+ error
+ The field "%s" on "%s" is not in the selection.
+ The field "%s" on "%s" is not in the selection.
+ ir
+
+
time_format_validation_record
en_US
diff --git a/trytond/model/modelsql.py b/trytond/model/modelsql.py
index 1e1cdc48c9..2f46d2422c 100644
--- a/trytond/model/modelsql.py
+++ b/trytond/model/modelsql.py
@@ -297,23 +297,6 @@ class ModelSQL(ModelStorage):
upd2.append(FIELDS[field._type].sql_format(value))
else:
upd_todo.append(fname)
- if (hasattr(field, 'selection')
- and field.selection
- and value):
- if field._type == 'reference':
- if isinstance(value, basestring):
- value = value.split(',')[0]
- else:
- value, _ = value
- if isinstance(field.selection, (tuple, list)):
- test = dict(field.selection)
- else:
- test = dict(getattr(cls, field.selection)())
- if value not in test:
- raise Exception('ValidateError',
- 'The value "%s" for the field "%s" '
- 'is not in the selection'
- % (value, fname))
upd0 += ', create_uid, create_date'
upd1 += ', %s, %s'
upd2.append(Transaction().user)
@@ -788,30 +771,6 @@ class ModelSQL(ModelStorage):
upd_todo.append(field)
else:
updend.append(field)
- if field in cls._fields \
- and hasattr(cls._fields[field], 'selection') \
- and cls._fields[field].selection \
- and values[field]:
- if cls._fields[field]._type == 'reference':
- if isinstance(values[field], basestring):
- val = values[field].split(',')[0]
- else:
- val, _ = values[field]
- else:
- val = values[field]
- if isinstance(cls._fields[field].selection, (tuple, list)):
- if val not in dict(cls._fields[field].selection):
- raise Exception('ValidateError',
- 'The value "%s" for the field "%s" ' \
- 'is not in the selection' % \
- (val, field))
- else:
- if val not in dict(getattr(cls,
- cls._fields[field].selection)()):
- raise Exception('ValidateError',
- 'The value "%s" for the field "%s" ' \
- 'is not in the selection' % \
- (val, field))
upd0.append(('write_uid', '%s'))
upd0.append(('write_date', '%s'))
diff --git a/trytond/model/modelstorage.py b/trytond/model/modelstorage.py
index 61519ce96d..5114d59d28 100644
--- a/trytond/model/modelstorage.py
+++ b/trytond/model/modelstorage.py
@@ -1059,6 +1059,28 @@ class ModelStorage(Model):
digits_test(getattr(record, field_name),
field.digits, field_name)
+ # validate selection
+ if hasattr(field, 'selection') and field.selection:
+ if isinstance(field.selection, (tuple, list)):
+ test = set(dict(field.selection).keys())
+ else:
+ test = set(dict(getattr(cls,
+ field.selection)()).keys())
+ # None and '' are equivalent
+ if '' in test or None in test:
+ test.add('')
+ test.add(None)
+ for record in records:
+ value = getattr(record, field_name)
+ if field._type == 'reference':
+ if isinstance(value, ModelStorage):
+ value = value.__class__.__name__
+ elif value:
+ value, _ = value.split(',')
+ if value not in test:
+ cls.raise_user_error('selection_validation_record',
+ error_args=cls._get_error_args(field_name))
+
def format_test(value, format, field_name):
if not value:
return
diff --git a/trytond/res/user.py b/trytond/res/user.py
index d30deaf96b..1e4abec61a 100644
--- a/trytond/res/user.py
+++ b/trytond/res/user.py
@@ -26,6 +26,7 @@ try:
TIMEZONES = [(x, x) for x in pytz.common_timezones]
except ImportError:
TIMEZONES = []
+TIMEZONES += [(None, '')]
__all__ = [
'User', 'UserAction', 'UserGroup', 'Warning_',
diff --git a/trytond/test/export_data.py b/trytond/test/export_data.py
index 4f05b000c0..8c9f3c635b 100644
--- a/trytond/test/export_data.py
+++ b/trytond/test/export_data.py
@@ -29,9 +29,10 @@ class ExportData(ModelSQL):
date = fields.Date('Date')
datetime = fields.DateTime('DateTime')
selection = fields.Selection([
- ('select1', 'Select 1'),
- ('select2', 'Select 2'),
- ], 'Selection')
+ (None, ''),
+ ('select1', 'Select 1'),
+ ('select2', 'Select 2'),
+ ], 'Selection')
many2one = fields.Many2One('test.export_data.target',
'Many2One')
many2many = fields.Many2Many('test.export_data.relation',
@@ -39,8 +40,9 @@ class ExportData(ModelSQL):
one2many = fields.One2Many('test.export_data.target', 'one2many',
'One2Many')
reference = fields.Reference('Reference', [
- ('test.export_data.target', 'Target'),
- ])
+ (None, ''),
+ ('test.export_data.target', 'Target'),
+ ])
class ExportDataTarget2:
diff --git a/trytond/test/import_data.py b/trytond/test/import_data.py
index 0dd816bd88..1f62d9ae07 100644
--- a/trytond/test/import_data.py
+++ b/trytond/test/import_data.py
@@ -73,9 +73,10 @@ class ImportDataSelection(ModelSQL):
"Import Data Selection"
__name__ = 'test.import_data.selection'
selection = fields.Selection([
- ('select1', 'Select 1'),
- ('select2', 'Select 2'),
- ], 'Selection')
+ (None, ''),
+ ('select1', 'Select 1'),
+ ('select2', 'Select 2'),
+ ], 'Selection')
class ImportDataMany2OneTarget(ModelSQL):
@@ -136,5 +137,6 @@ class ImportDataReference(ModelSQL):
"Import Data Reference"
__name__ = 'test.import_data.reference'
reference = fields.Reference('Reference', [
- ('test.import_data.reference.selection', 'Test'),
- ])
+ (None, ''),
+ ('test.import_data.reference.selection', 'Test'),
+ ])
diff --git a/trytond/test/test.py b/trytond/test/test.py
index b855fc341c..bd18f5f612 100644
--- a/trytond/test/test.py
+++ b/trytond/test/test.py
@@ -429,6 +429,7 @@ class One2ManyReferenceTarget(ModelSQL):
__name__ = 'test.one2many_reference.target'
name = fields.Char('Name', required=True)
origin = fields.Reference('Origin', [
+ (None, ''),
('test.one2many_reference', 'One2Many Reference'),
])
@@ -520,6 +521,7 @@ class Many2ManyReferenceRelation(ModelSQL):
'Many2Many Relation'
__name__ = 'test.many2many_reference.relation'
origin = fields.Reference('Origin', [
+ (None, ''),
('test.many2many_reference', 'Many2Many Reference'),
])
target = fields.Many2One('test.many2many_reference.target',
@@ -551,6 +553,7 @@ class Reference(ModelSQL):
__name__ = 'test.reference'
name = fields.Char('Name', required=True)
reference = fields.Reference('Reference', selection=[
+ (None, ''),
('test.reference.target', 'Target'),
])
@@ -566,6 +569,7 @@ class ReferenceRequired(ModelSQL):
__name__ = 'test.reference_required'
name = fields.Char('Name', required=True)
reference = fields.Reference('Reference', selection=[
+ (None, ''),
('test.reference.target', 'Target'),
], required=True)
@@ -578,6 +582,7 @@ class Property(ModelSQL):
'Test Many2One'))
numeric = fields.Property(fields.Numeric('Test Numeric'))
selection = fields.Property(fields.Selection([
+ (None, ''),
('option_a', 'Option A'),
('option_b', 'Option B')
], 'Test Selection'))