From 507358c4e8c79fe52f0a289cc059ca0e5ef9fd7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 25 Jul 2012 21:01:29 +0200 Subject: [PATCH] Allow to use tuple for Reference review437001 --- CHANGELOG | 1 + doc/ref/models/fields.rst | 2 + trytond/backend/fields.py | 9 ++- trytond/model/modelsql.py | 10 ++- trytond/test/test.py | 33 ++++++++ trytond/tests/test_fields.py | 149 ++++++++++++++++++++++++++++++++++- 6 files changed, 200 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c278ed60fb..231186c8cf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Allow to use tuple for Reference * Add constant interpolation on line graph * Add create/delete field access * Add dynamic size limit on the One2Many, Many2Many and Char diff --git a/doc/ref/models/fields.rst b/doc/ref/models/fields.rst index 5eea03d211..8120b87495 100644 --- a/doc/ref/models/fields.rst +++ b/doc/ref/models/fields.rst @@ -358,6 +358,8 @@ a ``str`` instance like this:: ',' +But a ``tuple`` can be used to search or set value. + :class:`Reference` has one extra optional argument: .. attribute:: Reference.selection diff --git a/trytond/backend/fields.py b/trytond/backend/fields.py index 84e07cc46c..ec57061c8c 100644 --- a/trytond/backend/fields.py +++ b/trytond/backend/fields.py @@ -161,7 +161,14 @@ class Selection(Char): class Reference(Char): - pass + + @staticmethod + def sql_format(value): + try: + value = '%s,%s' % tuple(value) + except TypeError, e: + pass + return Char.sql_format(value) class Many2One(Field): diff --git a/trytond/model/modelsql.py b/trytond/model/modelsql.py index 071242024c..2feb55454b 100644 --- a/trytond/model/modelsql.py +++ b/trytond/model/modelsql.py @@ -300,7 +300,10 @@ class ModelSQL(ModelStorage): and self._columns[field].selection \ and values[field]: if self._columns[field]._type == 'reference': - val = values[field].split(',')[0] + if isinstance(values[field], basestring): + val = values[field].split(',')[0] + else: + val, _ = values[field] else: val = values[field] if isinstance(self._columns[field].selection, (tuple, list)): @@ -799,7 +802,10 @@ class ModelSQL(ModelStorage): and self._columns[field].selection \ and values[field]: if self._columns[field]._type == 'reference': - val = values[field].split(',')[0] + if isinstance(values[field], basestring): + val = values[field].split(',')[0] + else: + val, _ = values[field] else: val = values[field] if isinstance(self._columns[field].selection, (tuple, list)): diff --git a/trytond/test/test.py b/trytond/test/test.py index 38cd740515..1366c9718d 100644 --- a/trytond/test/test.py +++ b/trytond/test/test.py @@ -700,6 +700,39 @@ class Many2ManySizeRelation(ModelSQL): Many2ManySizeRelation() +class Reference(ModelSQL): + 'Reference' + _name = 'test.reference' + _description = __doc__ + name = fields.Char('Name', required=True) + reference = fields.Reference('Reference', selection=[ + ('test.reference.target', 'Target'), + ]) + +Reference() + + +class ReferenceTarget(ModelSQL): + 'Reference Target' + _name = 'test.reference.target' + _description = __doc__ + name = fields.Char('Name', required=True) + +ReferenceTarget() + + +class ReferenceRequired(ModelSQL): + 'Reference Required' + _name = 'test.reference_required' + _description = __doc__ + name = fields.Char('Name', required=True) + reference = fields.Reference('Reference', selection=[ + ('test.reference.target', 'Target'), + ]) + +ReferenceRequired() + + class Property(ModelSQL): 'Property' _name = 'test.property' diff --git a/trytond/tests/test_fields.py b/trytond/tests/test_fields.py index 261e980807..8cd91d9fa8 100644 --- a/trytond/tests/test_fields.py +++ b/trytond/tests/test_fields.py @@ -94,6 +94,10 @@ class FieldsTestCase(unittest.TestCase): self.many2many_size = POOL.get('test.many2many_size') self.many2many_size_target = POOL.get('test.many2many_size.target') + self.reference = POOL.get('test.reference') + self.reference_target = POOL.get('test.reference.target') + self.reference_required = POOL.get('test.reference_required') + self.property_ = POOL.get('test.property') def test0010boolean(self): @@ -2864,7 +2868,150 @@ class FieldsTestCase(unittest.TestCase): transaction.cursor.rollback() - def test0140property(self): + def test0140reference(self): + ''' + Test Reference. + ''' + with Transaction().start(DB_NAME, USER, + context=CONTEXT) as transaction: + target1_id = self.reference_target.create({ + 'name': 'target1', + }) + reference1_id = self.reference.create({ + 'name': 'reference1', + 'reference': 'test.reference.target,%s' % target1_id, + }) + self.assert_(reference1_id) + + reference1 = self.reference.read(reference1_id, ['reference']) + self.assertEqual(reference1['reference'], + 'test.reference.target,%s' % target1_id) + + reference_ids = self.reference.search([ + ('reference', '=', + 'test.reference.target,%s' % target1_id), + ]) + self.assertEqual(reference_ids, [reference1_id]) + + reference_ids = self.reference.search([ + ('reference', '=', + ('test.reference.target', target1_id)), + ]) + self.assertEqual(reference_ids, [reference1_id]) + + reference_ids = self.reference.search([ + ('reference', '=', + ['test.reference.target', target1_id]), + ]) + self.assertEqual(reference_ids, [reference1_id]) + + reference_ids = self.reference.search([ + ('reference', '!=', + 'test.reference.target,%s' % target1_id), + ]) + self.assertEqual(reference_ids, []) + + reference_ids = self.reference.search([ + ('reference', '!=', + ('test.reference.target', target1_id)), + ]) + self.assertEqual(reference_ids, []) + + reference_ids = self.reference.search([ + ('reference', 'in', + ['test.reference.target,%s' % target1_id]), + ]) + self.assertEqual(reference_ids, [reference1_id]) + + reference_ids = self.reference.search([ + ('reference', 'in', + [('test.reference.target', target1_id)]), + ]) + self.assertEqual(reference_ids, [reference1_id]) + + reference_ids = self.reference.search([ + ('reference', 'in', [None]), + ]) + self.assertEqual(reference_ids, []) + + reference_ids = self.reference.search([ + ('reference', 'not in', + ['test.reference.target,%s' % target1_id]), + ]) + self.assertEqual(reference_ids, []) + + reference_ids = self.reference.search([ + ('reference', 'not in', + [('test.reference.target', target1_id)]), + ]) + self.assertEqual(reference_ids, []) + + reference_ids = self.reference.search([ + ('reference', 'not in', [None]), + ]) + self.assertEqual(reference_ids, [reference1_id]) + + reference2_id = self.reference.create({ + 'name': 'reference2', + }) + self.assert_(reference2_id) + + reference2 = self.reference.read(reference2_id, ['reference']) + self.assertEqual(reference2['reference'], None) + + reference_ids = self.reference.search([ + ('reference', '=', None), + ]) + self.assertEqual(reference_ids, [reference2_id]) + + target2_id = self.reference_target.create({ + 'name': 'target2', + }) + + self.reference.write(reference2_id, { + 'reference': 'test.reference.target,%s' % target2_id, + }) + reference2 = self.reference.read(reference2_id, ['reference']) + self.assertEqual(reference2['reference'], + 'test.reference.target,%s' % target2_id) + + self.reference.write(reference2_id, { + 'reference': None, + }) + reference2 = self.reference.read(reference2_id, ['reference']) + self.assertEqual(reference2['reference'], None) + + self.reference.write(reference2_id, { + 'reference': ('test.reference.target', target2_id), + }) + reference2 = self.reference.read(reference2_id, ['reference']) + self.assertEqual(reference2['reference'], + 'test.reference.target,%s' % target2_id) + + reference3_id = self.reference.create({ + 'name': 'reference3', + 'reference': ('test.reference.target', target1_id), + }) + self.assert_(reference3_id) + + self.assertRaises(Exception, self.reference_required.create, { + 'name', 'reference4', + }) + transaction.cursor.rollback() + + target4_id = self.reference_target.create({ + 'name': 'target4_id', + }) + + reference4_id = self.reference_required.create({ + 'name': 'reference4', + 'reference': 'test.reference.target,%s' % target4_id, + }) + self.assert_(reference4_id) + + transaction.cursor.rollback() + + def test0150property(self): ''' Test Property with supported field types. '''