Added equality methods to Choices objects, and overrode + for Choices

for easy concatenation with other Choices and choice-like iterables.
Also wrote tests for them, and extended the readme to reflect this
This commit is contained in:
Tony Aldridge 2013-08-23 16:58:10 +01:00
parent f7584e3972
commit 003ad70805
3 changed files with 109 additions and 0 deletions

View file

@ -99,6 +99,20 @@ the third is the human-readable version:
# ...
status = models.IntegerField(choices=STATUS, default=STATUS.draft)
Choices can be concatenated with the ``+`` operator, both to other Choices
instances and other iterable objects that could be converted into Choices:
.. code-block:: python
from model_utils import Choices
GENERIC_CHOICES = Choices((0, 'draft', _('draft')), (1, 'published', _('published')))
class Article(models.Model):
STATUS = GENERIC_CHOICES + [(2, 'featured', _('featured))]
# ...
status = models.IntegerField(choices=STATUS, default=STATUS.draft)
StatusField
===========

View file

@ -73,6 +73,28 @@ class Choices(object):
def __getitem__(self, index):
return self._choices[index]
def __add__(self, other):
if isinstance(other, self.__class__):
other = other._full
else:
other = list(other)
return Choices(*(self._full + other))
def __radd__(self, other):
if isinstance(other, self.__class__):
other = other._full
else:
other = list(other)
return Choices(*(other + self._full))
def __eq__(self, other):
if isinstance(other, self.__class__):
return self._full == other._full
return False
def __ne__(self, other):
return not self.__eq__(other)
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__,
', '.join(("%s" % repr(i) for i in self._full)))

View file

@ -220,6 +220,15 @@ class ChoicesTests(TestCase):
self.assertRaises(ValueError, Choices, ('a',))
def test_equality(self):
self.assertEqual(self.STATUS, Choices('DRAFT', 'PUBLISHED'))
def test_composability(self):
self.assertEqual(Choices('DRAFT') + Choices('PUBLISHED'), self.STATUS)
self.assertEqual(Choices('DRAFT') + ('PUBLISHED',), self.STATUS)
self.assertEqual(('DRAFT',) + Choices('PUBLISHED'), self.STATUS)
class LabelChoicesTests(ChoicesTests):
def setUp(self):
@ -254,6 +263,14 @@ class LabelChoicesTests(ChoicesTests):
self.assertEqual(len(self.STATUS), 3)
def test_equality(self):
self.assertEqual(self.STATUS, Choices(
('DRAFT', 'is draft'),
('PUBLISHED', 'is published'),
'DELETED',
))
def test_repr(self):
self.assertEqual(repr(self.STATUS), "Choices" + repr((
('DRAFT', 'DRAFT', 'is draft'),
@ -262,6 +279,22 @@ class LabelChoicesTests(ChoicesTests):
)))
def test_composability(self):
self.assertEqual(
Choices(('DRAFT', 'is draft',)) + Choices(('PUBLISHED', 'is published'), 'DELETED'),
self.STATUS
)
self.assertEqual(
(('DRAFT', 'is draft',),) + Choices(('PUBLISHED', 'is published'), 'DELETED'),
self.STATUS
)
self.assertEqual(
Choices(('DRAFT', 'is draft',)) + (('PUBLISHED', 'is published'), 'DELETED'),
self.STATUS
)
class IdentifierChoicesTests(ChoicesTests):
def setUp(self):
@ -298,6 +331,46 @@ class IdentifierChoicesTests(ChoicesTests):
)))
def test_equality(self):
self.assertEqual(self.STATUS, Choices(
(0, 'DRAFT', 'is draft'),
(1, 'PUBLISHED', 'is published'),
(2, 'DELETED', 'is deleted'))
)
def test_composability(self):
self.assertEqual(
Choices(
(0, 'DRAFT', 'is draft'),
(1, 'PUBLISHED', 'is published')
) + Choices(
(2, 'DELETED', 'is deleted'),
),
self.STATUS
)
self.assertEqual(
Choices(
(0, 'DRAFT', 'is draft'),
(1, 'PUBLISHED', 'is published')
) + (
(2, 'DELETED', 'is deleted'),
),
self.STATUS
)
self.assertEqual(
(
(0, 'DRAFT', 'is draft'),
(1, 'PUBLISHED', 'is published')
) + Choices(
(2, 'DELETED', 'is deleted'),
),
self.STATUS
)
class InheritanceManagerTests(TestCase):
def setUp(self):
self.child1 = InheritanceManagerTestChild1.objects.create()