Metadata-Version: 2.0
Name: django-echoices
Version: 2.0.0
Summary: Choices for Django model fields as enumeration
Home-page: https://github.com/mbourqui/django-echoices
Author: Marc Bourqui
Author-email: https://github.com/mbourqui
License: GNU GPLv3
Keywords: django choices models enum
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 1.8
Classifier: Framework :: Django :: 1.9
Classifier: Framework :: Django :: 1.10
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Utilities
Requires-Dist: Django (>=1.8.18)

|Python| |Django| |License| |PyPI| |Build Status| |Coverage Status|

Django-EChoices, choices for Django model fields as enumeration
===============================================================

Features
--------

-  Specialized `enum types <#enum>`__
-  Specialized `model fields <#modelfield>`__

Requirements
------------

-  Django >= 1.8.18

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

1. Run ``pip install django-echoices``

Usage
-----

Enumeration
~~~~~~~~~~~

First, define your choices enumeration (in your ``models.py`` for
example):

::

    from echoices.enums import EChoice

    class EStates(EChoice):
        # format is: (value -> char or str or int, label -> str)
        CREATED = ('c', 'Created')
        SUBMITTED = ('s', 'Submitted')

Model field
~~~~~~~~~~~

Regular model field
^^^^^^^^^^^^^^^^^^^

Then, either use a regular model field:

::

    from django.db import models

    class MyModel(models.Model):
        state = models.CharField(max_length=EStates.max_value_length(),
                                 choices=EStates.choices(),
                                 default=EStates.CREATED.value)

**Note**: If your value is an ``int``, you can use
``models.IntegerField`` instead.

Specialized field
^^^^^^^^^^^^^^^^^

You can also use specialized field. Using such a field, you will then
only handle ``Echoice`` instances.

::

    from django.db import models
    from echoices.fields import make_echoicefield

    class MyModel(models.Model):
        # `max_length` is set automatically
        state = make_echoicefield(EStates, default=EStates.CREATED)

**Note**: ``MyModel.state`` will be ``Estates`` instance stored in a
``EStatesField`` field. See `documentation <#modelfield>`__ for more
details.

Derivation
~~~~~~~~~~

You can add your own fields to the ``value`` and ``label`` ones. To do
so, you have to override the **init**\ () and your signature must look
like: ``self, value, label, *args`` where you replace ``*args`` with
your own positional arguments, as you would do when defining a custom
Enum. Do *not* call the super().\ **init**\ (), as ``value`` and
``label`` are already set internally by ``EChoice``.

As when dealing with a derived Enum, you can also add your own methods.

::

    from echoices.enums import EChoice

    class EMyChoices(EChoice):
        """Another variant of EChoice with additionnal content"""

        MY_CHOICE = (1, 'First choice', 'my additional value')

        def __init__(self, value, label, my_arg):
            self.my_arg = my_arg
            # Note: super().__init__() shall *not* be called!

        def show_myarg(self):
            """Used as: EMyChoices.MY_CHOICE.show_myarg()"""
            print(self.my_arg)

        @classmethod
        def show_all(cls):
            """Used as: EMyChoices.show_all()"""
            print(", ".join([e.my_arg for e in list(cls)]))

Short documentation
-------------------

Specialized enum types
~~~~~~~~~~~~~~~~~~~~~~

``enums.EChoice``
^^^^^^^^^^^^^^^^^

Base enum type. Each enum element is a tuple ``(value, label)``, where
[t]he first element in each tuple is the actual value to be set on the
model, and the second element is the human-readable name 
\ `doc <https://docs.djangoproject.com/en/1.11/ref/models/fields/#choices>`__\ .
Values **must** be unique. Can be derived for further customization.
#### ``enums.EOrderedChoice`` Supports ordering of elements.
``EOrderedChoice.choices()`` takes an extra optional argument,
``order``, which supports three values: 'sorted', 'reverse' or 'natural'
(default). If ``sorted``, the choices are ordered according to their
value. If ``reverse``, the choices are ordered according to their value
as if each comparison were reversed. If ``natural``, the order is the
one used when instantiating the enumeration. #### ``enums.EAutoChoice``
Generates auto-incremented numeric values. It's then used like:

::

    from echoices.enums import EAutoChoice

    class EStates(EAutoChoice):
        # format is: label -> str
        CREATED = 'Created'
        SUBMITTED = 'Submitted'

API
^^^

Overriden EnumMeta methods
''''''''''''''''''''''''''

-  ``EChoice.__getitem__()``, such that you can retrieve an ``EChoice``
   instance using ``EChoice['my_value']``

Additional classmethods
'''''''''''''''''''''''

-  ``choices()`` generates the choices as expected by a Django model
   field
-  ``max_value_length()`` returns the max length for the Django model
   field, if the values are strings
-  ``values()`` returns a list of all the values
-  ``get(value, default=None)`` returns the EChoice instance having that
   value, else returns the default

Specialized model fields
~~~~~~~~~~~~~~~~~~~~~~~~

``fields.EChoiceField`` via ``fields.make_echoicefield()``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Deal directly with the enum instances instead of their DB storage value.
The specialized field will be derived from a ``models.Field`` subclass,
the internal representation is deduced from the value type. So for
example if the values are strings, then the the ``EChoiceField`` will
subclass ``models.CharField``; and if the values are integers then it
will be ``models.IntegerField``. Actually supports ``str``, ``int``,
``float`` and (non-null) ``bool`` as enum values.

``make_echoicefield()`` will return an instance of ``EChoiceField``
which subclasses a field type from ``models.CharField``. The exact name
of the field type will be ``MyEnumNameField`` in Django >= 1.9, note the
suffixed 'Field'. For earlier versions of Django, it will be
``EChoiceField``.

Thus, ``MyModel.my_echoice_field`` will be an ``EChoice`` instance
stored in an ``EChoiceField`` field.

``fields.MultipleEChoiceField``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Similar to previous fields, but supports multiple values to be selected.
`**Not yet implemented** <#3>`__.

.. |Python| image:: https://img.shields.io/badge/Python-3.4,3.5,3.6-blue.svg?style=flat-square
   :target: /
.. |Django| image:: https://img.shields.io/badge/Django-1.8,1.9,1.10-blue.svg?style=flat-square
   :target: /
.. |License| image:: https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat-square
   :target: /LICENSE
.. |PyPI| image:: https://img.shields.io/pypi/v/django_echoices.svg?style=flat-square
   :target: https://pypi.python.org/pypi/django-echoices
.. |Build Status| image:: https://travis-ci.org/mbourqui/django-echoices.svg?branch=master
   :target: https://travis-ci.org/mbourqui/django-echoices
.. |Coverage Status| image:: https://coveralls.io/repos/github/mbourqui/django-echoices/badge.svg?branch=master
   :target: https://coveralls.io/github/mbourqui/django-echoices?branch=master


