django-choice-enumfields 1.1.3
Real Python Enums for Django.
License: MIT

This package lets you use real Python (PEP435_-style) enums with Django.

.. image:: https://travis-ci.org/druids/django-choice-enumfields.svg?branch=master
    :target: https://travis-ci.org/druids/django-choice-enumfields


Installation
------------

1. ``pip install django-choice-enumfields``


Included Tools
--------------


EnumField, NumEnumField
```````````````````````

.. code-block:: python

    from enumfields import EnumField
    from enumfields import ChoiceEnum  # Uses Ethan Furman's "enum34" backport

    class Color(ChoiceEnum):
        RED = 'r'
        GREEN = 'g'
        BLUE = 'b'

    class MyModel(models.Model):

        color = EnumField(Color, max_length=1)

Elsewhere:

.. code-block:: python

    m = MyModel.objects.filter(color=Color.RED)

``NumEnumField`` works identically, but the underlying storage mechanism is
an ``IntegerField`` instead of a ``CharField``.


EnumSubField, NumEnumSubField
`````````````````````````````

.. code-block:: python

    from enumfields import EnumField, EnumSubField
    from enumfields import ChoiceEnum

    class Color(ChoiceEnum):
        RED = 'r'
        GREEN = 'g'
        BLUE = 'b'

    class ColorType(ChoiceEnum):
        LIGHT = Choice('l', 'light', parents=(Color.RED, Color.BLUE))
        DARK = Choice('d', 'dark', parents=(Color.RED, Color.GREEN))
        TRANSPARENT = Choice('t', 'transparent', parents=(Color.GREEN))

    class MyModel(models.Model):

        color = EnumField(Color, max_length=1)
        color_type = EnumSubField('color', ColorType, max_length=1)

    MyModel(color=Color.RED, color_type=ColorType.LIGHT).full_clean()  # OK
    MyModel(color=Color.RED, color_type=ColorType.TRANSPARENT).full_clean()  # Raise ValidationError

``EnumSubField`` automatically validates if parents requirement is satisfied.

With ``EnumSubField``, ``EnumField``, ``NumEnumSubField`` and ``NumEnumField``
comes validation of initial and allowed transitions between choices out of the box.

.. code-block:: python

    from enumfields import EnumField
    from enumfields import Choice, ChoiceEnum

    class StateFlow(ChoiceEnum):
        START = Choice('s', 'start', next={'PROCESSING'})
        PROCESSING = Choice('p', 'processing', next={'END'}, initial=False)
        END = Choice('e', 'end', next=set(), initial=False)

    class MyModel(models.Model):

        state = EnumField(StateFlow, max_length=1)

    MyModel(state=StateFlow.START).full_clean()  # OK

    # Raise ValidationError because PROCESSING is not in initial states
    MyModel(state=StateFlow.PROCESSING).full_clean()

    model = MyModel.objects.create(StateFlow.START)
    model.state = StateFlow.END
    # Raise ValidationError because END is not next state after START
    model.full_clean()

    model.state = StateFlow.PROCESSING
    model.full_clean()  # OK


Usage in Forms
~~~~~~~~~~~~~~

Call the ``formfield`` method to use an ``EnumField`` directly in a ``Form``.

.. code-block:: python

    class MyForm(forms.Form):

        color = EnumField(Color, max_length=1).formfield()

ChoiceEnum
``````````

Normally, you just use normal PEP435_-style enums, however, django-choice-enumfields
also encludes its own version of ChoiceEnum with a few extra bells and whistles.
Namely, the smart definition of labels which are used, for example, in admin
dropdowns. By default, it will create labels by title-casing your constant
names. You can provide custom labels with using Choice to define enum item.

.. code-block:: python

    from enumfields import EnumField, ChoiceEnum, Choice  # Our own Enum class

    class Color(ChoiceEnum):
        RED = Choice('r', 'A custom label')
        GREEN = 'g'
        BLUE = 'b'

    class MyModel(models.Model):
        color = EnumField(Color, max_length=1)

    assert Color.GREEN.label == 'Green'
    assert Color.RED.label == 'A custom label'


.. _PEP435: http://www.python.org/dev/peps/pep-0435/


EnumFieldListFilter
```````````````````

``enumfields.admin.EnumFieldListFilter`` is provided to allow using enums in
``list_filter``.


.. code-block:: python

    from enumfields.admin import EnumFieldListFilter

    class MyModelAdmin(admin.ModelAdmin):
      list_filter = [('color', EnumFieldListFilter)]