diff --git a/changelog b/changelog index a908f720..8f14d773 100644 --- a/changelog +++ b/changelog @@ -8,6 +8,7 @@ CHANGELOG * clear TTL and timestamp off models after persisting to DB * allows UUID without - (Thanks to Michael Haddad, github.com/mahall) * fixes regarding syncing schema settings (thanks Kai Lautaportti github.com/dokai) +* allow acces to instance columns as if it is a dict 0.10.0 diff --git a/cqlengine/models.py b/cqlengine/models.py index 4f70c3ee..27f0316b 100644 --- a/cqlengine/models.py +++ b/cqlengine/models.py @@ -421,6 +421,37 @@ class BaseModel(object): val = col.validate(getattr(self, name)) setattr(self, name, val) + ### Let an instance be used like a dict of its columns keys/values + + def __iter__(self): + """ Iterate over column ids. """ + for column_id in self._columns.keys(): + yield column_id + + def __getitem__(self, key): + """ Returns column's value. """ + if not isinstance(key, basestring): + raise TypeError + if key not in self._columns.keys(): + raise KeyError + return getattr(self, key) + + def __len__(self): + """ Returns the number of columns defined on that model. """ + return len(self._columns.keys()) + + def keys(self): + """ Returns list of column's IDs. """ + return [k for k in self] + + def values(self): + """ Returns list of column's values. """ + return [self[k] for k in self] + + def items(self): + """ Returns a dictionnary of columns's IDs/values. """ + return [(k, self[k]) for k in self] + def _as_dict(self): """ Returns a map of column names to cleaned values """ values = self._dynamic_columns or {} diff --git a/cqlengine/tests/model/test_model_io.py b/cqlengine/tests/model/test_model_io.py index 82abef74..512aa232 100644 --- a/cqlengine/tests/model/test_model_io.py +++ b/cqlengine/tests/model/test_model_io.py @@ -1,6 +1,7 @@ from uuid import uuid4 import random from datetime import date +from operator import itemgetter from cqlengine.tests.base import BaseCassEngTestCase from cqlengine.management import create_table @@ -43,6 +44,26 @@ class TestModelIO(BaseCassEngTestCase): for cname in tm._columns.keys(): self.assertEquals(getattr(tm, cname), getattr(tm2, cname)) + def test_model_read_as_dict(self): + """ + Tests that columns of an instance can be read as a dict. + """ + tm = TestModel.create(count=8, text='123456789', a_bool=True) + column_dict = { + 'id': tm.id, + 'count': tm.count, + 'text': tm.text, + 'a_bool': tm.a_bool, + } + self.assertEquals(sorted(tm.keys()), sorted(column_dict.keys())) + self.assertEquals(sorted(tm.values()), sorted(column_dict.values())) + self.assertEquals( + sorted(tm.items(), key=itemgetter(0)), + sorted(column_dict.items(), key=itemgetter(0))) + self.assertEquals(len(tm), len(column_dict)) + for column_id in column_dict.keys(): + self.assertEqual(tm[column_id], column_dict[column_id]) + def test_model_updating_works_properly(self): """ Tests that subsequent saves after initial model creation work