Skip to content

Commit

Permalink
Support direct dictionary assignment to KeyValueField
Browse files Browse the repository at this point in the history
  • Loading branch information
ramast committed Feb 9, 2016
1 parent ecfc4ea commit dfd4971
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 9 deletions.
24 changes: 17 additions & 7 deletions model_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,24 +362,32 @@ 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 = []
for key, val in six.iteritems(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__()

Expand Down Expand Up @@ -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):
Expand Down
3 changes: 1 addition & 2 deletions tests/test_key_value_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"})
Expand Down

0 comments on commit dfd4971

Please sign in to comment.