Skip to content

druids/django-choice-enumfields

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

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

Installation

  1. pip install django-choice-enumfields

Included Tools

EnumField, NumEnumField

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:

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

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

EnumSubField, NumEnumSubField

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.

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.

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.

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'

EnumFieldListFilter

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

from enumfields.admin import EnumFieldListFilter

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

About

Real Python Enums for Django

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 100.0%