Skip to content

Commit

Permalink
Fixes bigjason#47 -- add public api to get attribute name from value
Browse files Browse the repository at this point in the history
  • Loading branch information
sergei-maertens committed Feb 22, 2017
1 parent 4487d3f commit 9691870
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
20 changes: 20 additions & 0 deletions djchoices/choices.py
Expand Up @@ -34,8 +34,25 @@ def __init__(self, value):
def __get__(self, obj, objtype):
return self.value


class Attributes(object):

def __init__(self, attrs, fields):
self.attrs = attrs
self.fields = fields

def __get__(self, obj, objtype):
if len(self.attrs) != len(self.fields):
raise ValueError(
'Not all values are unique, it\'s not possible to map all '
'values to the right attribute'
)
return self.attrs


# End Support Functionality


sentinel = object()


Expand Down Expand Up @@ -73,6 +90,7 @@ def __new__(cls, name, bases, attrs):
fields = {}
labels = Labels()
values = OrderedDict()
attributes = OrderedDict()
choices = []

# Get all the fields from parent classes.
Expand Down Expand Up @@ -103,6 +121,7 @@ def __new__(cls, name, bases, attrs):
attrs[field_name] = StaticProp(val0)
setattr(labels, field_name, label)
values[val0] = label
attributes[val0] = field_name
else:
choices.append((field_name, val.choices))

Expand All @@ -111,6 +130,7 @@ def __new__(cls, name, bases, attrs):
attrs["values"] = values
attrs["_fields"] = fields
attrs["validator"] = ChoicesValidator(values)
attrs["attributes"] = Attributes(attributes, fields)

return super(DjangoChoicesMeta, cls).__new__(cls, name, bases, attrs)

Expand Down
16 changes: 16 additions & 0 deletions djchoices/tests/test_choices.py
Expand Up @@ -39,6 +39,11 @@ class NullBooleanValueClass(DjangoChoices):
Option3 = ChoiceItem(False, "Failed")


class DuplicateValuesClass(DjangoChoices):
Option1 = ChoiceItem('a')
Option2 = ChoiceItem('a')


class DjangoChoices(unittest.TestCase):
def setUp(self):
pass
Expand Down Expand Up @@ -183,3 +188,14 @@ def test_deconstructible_validator(self):
self.assertEqual(deconstructed, (
'djchoices.choices.ChoicesValidator', (NumericTestClass.values,), {}
))

def test_attribute_from_value(self):
attributes = NumericTestClass.attributes
self.assertEqual(attributes[0], 'Item_0')
self.assertEqual(attributes[1], 'Item_1')
self.assertEqual(attributes[2], 'Item_2')
self.assertEqual(attributes[3], 'Item_3')

def test_attribute_from_value_duplicates(self):
with self.assertRaises(ValueError):
DuplicateValuesClass.attributes

0 comments on commit 9691870

Please sign in to comment.