deprecate ChoiceEnum and document Choices

This commit is contained in:
Carl Meyer 2010-04-15 22:54:37 -04:00
parent 02b2082e90
commit fecda79f5c
3 changed files with 34 additions and 43 deletions

View file

@ -7,7 +7,7 @@ Django model mixins and utilities.
Installation
============
Install from PyPI with ``easy_install`` or ``pip``::
Install from PyPI with ``pip``::
pip install django-model-utils
@ -28,34 +28,30 @@ Dependencies
.. _Django: http://www.djangoproject.com/
ChoiceEnum
==========
Choices
=======
``ChoiceEnum`` makes setting ``choices`` on a Django model field way
``Choices`` makes setting ``choices`` on a Django model field way
too easy::
from model_utils import ChoiceEnum
from model_utils import Choices
class Article(models.Model):
STATUS = ChoiceEnum('draft', 'published')
STATUS = Choices('draft', 'published')
# ...
status = models.PositiveIntegerField(choices=STATUS, default=STATUS.draft)
status = models.CharField(choices=STATUS, default=STATUS.draft, max_length=20)
def status_desc(self):
return self.STATUS[self.status]
A ``Choices`` object is initialized with any number of choices, which
can either be a string ID or a tuple of (string ID, human-readable
version). If a string ID is given alone, the ID itself is used as the
human-readable version. Accessing the string ID as an attribute on
the ``Choices`` object returns the human-readable version. If iterated
over, a ``ChoiceEnum`` object yields a tuple of two-tuples linking id
to text names, the format expected by the ``choices`` attribute of
Django models.
A ``ChoiceEnum`` object is initialized with any number of choices,
which should be strings. It assigns a sequential id to each
choice. The numerical id for a choice is available through attribute
access (``STATUS.draft``), and the text name for a choice can be
obtained by indexing with the numerical id
(``self.STATUS[self.status]``). If iterated over, a ``ChoiceEnum``
object yields a tuple of two-tuples linking id to text names, the
format expected by the ``choices`` attribute of Django models.
Be careful not to add new choices in the middle of the list, as that
will change the numerical ids for all subsequent choices, which could
impact existing data.
.. note::
Whither ``ChoiceEnum``? It's been deprecated in favor of ``Choices``.
fields.SplitField
=================

View file

@ -1,5 +1,11 @@
class ChoiceEnum(object):
"""
DEPRECATED: Use ``Choices`` (below) instead. This class has less
flexibility for human-readable display, and greater potential for
surprising data corruption if new choices are inserted in the
middle of the list. Automatic assignment of numeric IDs is not
such a great idea after all.
A class to encapsulate handy functionality for lists of choices
for a Django model field.
@ -22,6 +28,9 @@ class ChoiceEnum(object):
"""
def __init__(self, *choices):
import warnings
warnings.warn("ChoiceEnum is deprecated, use Choices instead.",
PendingDeprecationWarning)
self._choices = tuple(enumerate(choices))
self._choice_dict = dict(self._choices)
self._reverse_dict = dict(((i[1], i[0]) for i in self._choices))
@ -48,10 +57,10 @@ class Choices(object):
A class to encapsulate handy functionality for lists of choices
for a Django model field.
Accepts as arguments either tuples mapping choice IDs (numeric or
text) to human-readable names, or simply choice IDs (in which case
the ID is also used as the human-readable name). When iterated
over, behaves as the standard Django choices tuple of two-tuples.
Accepts as arguments either tuples mapping choice IDs (strings) to
human-readable names, or simply choice IDs (in which case the ID
is also used as the human-readable name). When iterated over,
behaves as the standard Django choices tuple of two-tuples.
Attribute access allows conversion of choice ID to human-readable
name.

View file

@ -76,20 +76,6 @@ class SplitFieldTests(TestCase):
self.assertRaises(AttributeError, _invalid_assignment)
class ChoiceEnumTests(TestCase):
def setUp(self):
self.STATUS = ChoiceEnum('DRAFT', 'PUBLISHED')
def test_getattr(self):
self.assertEquals(self.STATUS.DRAFT, 0)
def test_getitem(self):
self.assertEquals(self.STATUS[1], 'PUBLISHED')
def test_iteration(self):
self.assertEquals(tuple(self.STATUS), ((0, 'DRAFT'), (1, 'PUBLISHED')))
class ChoicesTests(TestCase):
def setUp(self):
self.STATUS = Choices('DRAFT', 'PUBLISHED')
@ -103,15 +89,15 @@ class ChoicesTests(TestCase):
class LabelChoicesTests(ChoicesTests):
def setUp(self):
self.STATUS = Choices(
('DRAFT', 'draft'),
('PUBLISHED', 'published'),
('DRAFT', 'is draft'),
('PUBLISHED', 'is published'),
'DELETED',
)
def test_iteration(self):
self.assertEquals(tuple(self.STATUS), (
('DRAFT', 'draft'),
('PUBLISHED', 'published'),
('DRAFT', 'is draft'),
('PUBLISHED', 'is published'),
('DELETED', 'DELETED'))
)