From dfd4971fad2922b3bd2c44c32400ceb58ee071ba Mon Sep 17 00:00:00 2001 From: Ramast Magdy Date: Tue, 9 Feb 2016 17:08:12 +0800 Subject: [PATCH] Support direct dictionary assignment to KeyValueField --- model_helpers.py | 24 +++++++++++++++++------- tests/test_key_value_field.py | 3 +-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/model_helpers.py b/model_helpers.py index 431b2af..9818325 100644 --- a/model_helpers.py +++ b/model_helpers.py @@ -362,17 +362,18 @@ def __add__(self, other): class KeyValueContainer(dict): + def __init__(self, seq=None, separator="=", **kwargs): + super(KeyValueContainer, self).__init__() self.sep = separator if isinstance(seq, six.string_types): seq = self._parse_string(seq) - if seq: - super(KeyValueContainer, self).__init__(seq, **kwargs) - else: - super(KeyValueContainer, self).__init__(**kwargs) - # Ensure all values are converted to strings - for key, value in six.iteritems(self): - self[key] = six.text_type(value) + if seq is not None: + seq = dict(seq) + kwargs.update(seq) + + for key, value in six.iteritems(kwargs): + self.__setitem__(key, value) def __str__(self): result = [] @@ -380,6 +381,13 @@ def __str__(self): result.append(u"%s %s %s" % (key, self.sep, val)) return u"\n".join(result) + "\n" + def __setitem__(self, key, item): + if item is None: + item = "" + else: + item = six.text_type(item) + super(KeyValueContainer, self).__setitem__(key, item) + def __unicode__(self): return self.__str__() @@ -432,6 +440,8 @@ def contribute_to_class(self, cls, name, **kwargs): def set_value(self, obj, value): if isinstance(value, six.string_types): value = self.from_db_value(value) + elif not isinstance(value, KeyValueContainer): + value = KeyValueContainer(value) obj.__dict__[self.name] = value def get_value(self, obj): diff --git a/tests/test_key_value_field.py b/tests/test_key_value_field.py index 4709d6c..298ecb6 100644 --- a/tests/test_key_value_field.py +++ b/tests/test_key_value_field.py @@ -5,14 +5,13 @@ def test_key_value_field(): - from model_helpers import KeyValueContainer team = Team(name="Team1") test.assert_equal(team.options, {}) team.options = "name = Ramast" test.assert_equal(team.options, {"name": "Ramast"}) test.assert_equal(str(team.options), "name = Ramast\n") - team.options = KeyValueContainer(Age=30) + team.options = {"Age": 30} test.assert_equal(str(team.options), "Age = 30\n") # Notice int has been converted to string since we don't store value data type test.assert_equal(team.options, {"Age": "30"})