Merge "Recurse dictionary generation in model to_dict()"
This commit is contained in:
commit
1fbfd3c065
@ -15,6 +15,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import six
|
||||||
|
|
||||||
from sqlalchemy.orm import collections
|
from sqlalchemy.orm import collections
|
||||||
|
|
||||||
@ -22,19 +23,44 @@ from octavia.common import constants
|
|||||||
|
|
||||||
|
|
||||||
class BaseDataModel(object):
|
class BaseDataModel(object):
|
||||||
|
def to_dict(self, calling_classes=None, recurse=False, **kwargs):
|
||||||
# NOTE(brandon-logan) This does not discover dicts for relationship
|
|
||||||
# attributes.
|
|
||||||
def to_dict(self):
|
|
||||||
"""Converts a data model to a dictionary."""
|
"""Converts a data model to a dictionary."""
|
||||||
|
calling_classes = calling_classes or []
|
||||||
ret = {}
|
ret = {}
|
||||||
for attr in self.__dict__:
|
for attr in self.__dict__:
|
||||||
if attr.startswith('_'):
|
if attr.startswith('_') or not kwargs.get(attr, True):
|
||||||
continue
|
continue
|
||||||
if isinstance(getattr(self, attr), (BaseDataModel, list)):
|
value = self.__dict__[attr]
|
||||||
ret[attr] = None
|
|
||||||
|
if recurse:
|
||||||
|
if isinstance(getattr(self, attr), list):
|
||||||
|
ret[attr] = []
|
||||||
|
for item in value:
|
||||||
|
if isinstance(item, BaseDataModel):
|
||||||
|
if type(self) not in calling_classes:
|
||||||
|
ret[attr].append(
|
||||||
|
item.to_dict(calling_classes=(
|
||||||
|
calling_classes + [type(self)])))
|
||||||
|
else:
|
||||||
|
ret[attr] = None
|
||||||
|
else:
|
||||||
|
ret[attr] = item
|
||||||
|
elif isinstance(getattr(self, attr), BaseDataModel):
|
||||||
|
if type(self) not in calling_classes:
|
||||||
|
ret[attr] = value.to_dict(
|
||||||
|
calling_classes=calling_classes + [type(self)])
|
||||||
|
else:
|
||||||
|
ret[attr] = None
|
||||||
|
elif six.PY2 and isinstance(value, six.text_type):
|
||||||
|
ret[attr.encode('utf8')] = value.encode('utf8')
|
||||||
|
else:
|
||||||
|
ret[attr] = value
|
||||||
else:
|
else:
|
||||||
ret[attr] = self.__dict__[attr]
|
if isinstance(getattr(self, attr), (BaseDataModel, list)):
|
||||||
|
ret[attr] = None
|
||||||
|
else:
|
||||||
|
ret[attr] = value
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
|
@ -98,3 +98,58 @@ class TestTypeDataModelRenames(base.TestCase):
|
|||||||
type_dict = TestTypeTenantProject(tenant_id='1234').to_dict()
|
type_dict = TestTypeTenantProject(tenant_id='1234').to_dict()
|
||||||
self.assertEqual('1234', type_dict['project_id'])
|
self.assertEqual('1234', type_dict['project_id'])
|
||||||
self.assertNotIn('tenant_id', type_dict)
|
self.assertNotIn('tenant_id', type_dict)
|
||||||
|
|
||||||
|
|
||||||
|
class TestToDictModel(data_models.BaseDataModel):
|
||||||
|
def __init__(self, text, parent=None):
|
||||||
|
self.parent = parent
|
||||||
|
self.child = None
|
||||||
|
self.children = None
|
||||||
|
self.text = text
|
||||||
|
|
||||||
|
def set_children(self, children):
|
||||||
|
self.children = children
|
||||||
|
|
||||||
|
def set_child(self, child):
|
||||||
|
self.child = child
|
||||||
|
|
||||||
|
def set_parent(self, parent):
|
||||||
|
self.parent = parent
|
||||||
|
|
||||||
|
|
||||||
|
class TestDataModelToDict(base.TestCase):
|
||||||
|
RECURSED_RESULT = {'parent': None,
|
||||||
|
'text': 'parent_text',
|
||||||
|
'child': {'parent': None,
|
||||||
|
'text': 'child_text',
|
||||||
|
'child': None,
|
||||||
|
'children': None},
|
||||||
|
'children': [
|
||||||
|
{'parent': None,
|
||||||
|
'text': 'child1_text',
|
||||||
|
'child': None,
|
||||||
|
'children': None},
|
||||||
|
{'parent': None,
|
||||||
|
'text': 'child2_text',
|
||||||
|
'child': None,
|
||||||
|
'children': None}]}
|
||||||
|
|
||||||
|
NO_RECURSE_RESULT = {'parent': None,
|
||||||
|
'text': 'parent_text',
|
||||||
|
'child': None,
|
||||||
|
'children': None}
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestDataModelToDict, self).setUp()
|
||||||
|
self.model = TestToDictModel('parent_text')
|
||||||
|
self.model.set_child(TestToDictModel('child_text', self.model))
|
||||||
|
self.model.set_children([TestToDictModel('child1_text', self.model),
|
||||||
|
TestToDictModel('child2_text', self.model)])
|
||||||
|
|
||||||
|
def test_to_dict_no_recurse(self):
|
||||||
|
self.assertEqual(self.model.to_dict(),
|
||||||
|
self.NO_RECURSE_RESULT)
|
||||||
|
|
||||||
|
def test_to_dict_recurse(self):
|
||||||
|
self.assertEqual(self.model.to_dict(recurse=True),
|
||||||
|
self.RECURSED_RESULT)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user