Fixed indexing into Choices so its useful.

This commit is contained in:
Carl Meyer 2013-09-24 15:13:27 -06:00
parent 4b6a800050
commit 5a33ff760a
4 changed files with 22 additions and 8 deletions

View file

@ -4,6 +4,10 @@ CHANGES
master (unreleased)
-------------------
* Indexing into a ``Choices`` instance now translates database representations
to human-readable choice names, rather than simply indexing into an array of
choice tuples. (Indexing into ``Choices`` was previously not documented.)
* Fix bug in `InheritanceManager` with grandchild classes on Django 1.6+;
`select_subclasses('child', 'child__grandchild')` would only ever get to the
child class. Thanks Keryn Knight for report and proposed fix.

View file

@ -52,6 +52,13 @@ the third is the human-readable version:
STATUS = Choices((0, 'draft', _('draft')), (1, 'published', _('published')))
status = models.IntegerField(choices=STATUS, default=STATUS.draft)
You can index into a ``Choices`` instance to translate a database
representation to its display name:
.. code-block:: python
status_display = Article.STATUS[article.status]
Option groups can also be used with ``Choices``; in that case each
argument is a tuple consisting of the option group name and a list of
options, where each option in the list is either a string, a two-tuple,

View file

@ -46,8 +46,10 @@ class Choices(object):
self._triples = []
# list of choices as (db, human-readable) - can include optgroups
self._doubles = []
# dictionary mapping db representation to human-readable
self._display_map = {}
# dictionary mapping Python identifier to db representation
self._mapping = {}
self._identifier_map = {}
# set of db representations
self._db_values = set()
@ -55,7 +57,8 @@ class Choices(object):
def _store(self, triple, triple_collector, double_collector):
self._mapping[triple[1]] = triple[0]
self._identifier_map[triple[1]] = triple[0]
self._display_map[triple[0]] = triple[2]
self._db_values.add(triple[0])
triple_collector.append(triple)
double_collector.append((triple[0], triple[2]))
@ -104,13 +107,13 @@ class Choices(object):
def __getattr__(self, attname):
try:
return self._mapping[attname]
return self._identifier_map[attname]
except KeyError:
raise AttributeError(attname)
def __getitem__(self, index):
return self._doubles[index]
def __getitem__(self, key):
return self._display_map[key]
def __add__(self, other):

View file

@ -200,7 +200,7 @@ class ChoicesTests(TestCase):
def test_indexing(self):
self.assertEqual(self.STATUS[1], ('PUBLISHED', 'PUBLISHED'))
self.assertEqual(self.STATUS['PUBLISHED'], 'PUBLISHED')
def test_iteration(self):
@ -276,7 +276,7 @@ class LabelChoicesTests(ChoicesTests):
def test_indexing(self):
self.assertEqual(self.STATUS[1], ('PUBLISHED', 'is published'))
self.assertEqual(self.STATUS['PUBLISHED'], 'is published')
def test_default(self):
@ -380,7 +380,7 @@ class IdentifierChoicesTests(ChoicesTests):
def test_indexing(self):
self.assertEqual(self.STATUS[1], (1, 'is published'))
self.assertEqual(self.STATUS[1], 'is published')
def test_getattr(self):