• Stars
    star
    201
  • Rank 188,511 (Top 4 %)
  • Language
    Python
  • License
    MIT License
  • Created over 11 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Custom Django field for using enumerations of named constants

django-enumfield

Provides an enumeration Django model field (using IntegerField) with reusable enums and transition validation.

Build Status PyPi Version License Python Versions Wheel Coveralls github

Installation

Currently, we test Django versions 2.2-4.1 and Python versions 3.7-3.11.

Install django-enumfield in your Python environment:

$ pip install django-enumfield

Upgrading from django-enumfield 1.x? See the migration guide

For use with Django versions prior to 1.8 use version 1.2.1

For use with Django versions prior to 1.11 use version 1.5

Usage

Create an Enum-class and pass it as first argument to the Django model EnumField.

from django.db import models
from django_enumfield import enum


class BeerStyle(enum.Enum):
    LAGER = 0
    STOUT = 1
    WEISSBIER = 2


class Beer(models.Model):
    style = enum.EnumField(BeerStyle, default=BeerStyle.LAGER)


# Use .get to get enum values from either name or ints
print(BeerStyle.get("LAGER"))  # <BeerStyle.LAGER: 0>
print(BeerStyle.get(1))  # <BeerStyle.STOUT: 1>
print(BeerStyle.get(BeerStyle.WEISSBIER))  # <BeerStyle.WEISSBIER: 2>

# It's also possible to use the normal enum way to get the value
print(BeerStyle(1))  # <BeerStyle.STOUT: 1>
print(BeerStyle["LAGER"])  # <BeerStyle.LAGER: 0>

# The enum value has easy access to their value and name
print(BeerStyle.LAGER.value)  # 0
print(BeerStyle.LAGER.name)  # "LAGER"

For more information about Python 3 enums (which our Enum inherits, IntEnum to be specific) checkout the docs.

Setting the default value

You can also set default value on your enum class using __default__ attribute

from django.db import models
from django_enumfield import enum


class BeerStyle(enum.Enum):
    LAGER = 0
    STOUT = 1
    WEISSBIER = 2

    __default__ = LAGER


class BeerStyleNoDefault(enum.Enum):
    LAGER = 0


class Beer(models.Model):
    style_default_lager = enum.EnumField(BeerStyle)
    style_default_stout = enum.EnumField(BeerStyle, default=BeerStyle.STOUT)
    style_default_null = enum.EnumField(BeerStyleNoDefault, null=True, blank=True)


# When you set __default__ attribute, you can access default value via
# `.default()` method of your enum class
assert BeerStyle.default() == BeerStyle.LAGER

beer = Beer.objects.create()
assert beer.style_default_larger == BeerStyle.LAGER
assert beer.style_default_stout == BeerStyle.STOUT
assert beer.style_default_null is None

Labels

You can use your own labels for Enum items

from django.utils.translation import gettext_lazy
from django_enumfield import enum


class Animals(enum.Enum):
    CAT = 1
    DOG = 2
    SHARK = 3

    __labels__ = {
        CAT: gettext_lazy("Cat"),
        DOG: gettext_lazy("Dog"),
    }


print(Animals.CAT.label)  # "Cat"
print(Animals.SHARK.label)  # "SHARK"

# There's also classmethods for getting the label
print(Animals.get_label(2))  # "Dog"
print(Animals.get_label("DOG"))  # "Dog"

Validate transitions

The Enum-class provides the possibility to use transition validation.

from django.db import models
from django_enumfield import enum
from django_enumfield.exceptions import InvalidStatusOperationError


class PersonStatus(enum.Enum):
    ALIVE = 1
    DEAD = 2
    REANIMATED = 3

    __transitions__ = {
        DEAD: (ALIVE,),  # Can go from ALIVE to DEAD
        REANIMATED: (DEAD,)  # Can go from DEAD to REANIMATED
    }


class Person(models.Model):
    status = enum.EnumField(PersonStatus)

# These transitions state that a PersonStatus can only go to DEAD from ALIVE and to REANIMATED from DEAD.
person = Person.objects.create(status=PersonStatus.ALIVE)
try:
    person.status = PersonStatus.REANIMATED
except InvalidStatusOperationError:
    print("Person status can not go from ALIVE to REANIMATED")
else:
    # All good
    person.save()

In forms

The Enum-class can also be used without the EnumField. This is very useful in Django form ChoiceFields.

from django import forms
from django_enumfield import enum
from django_enumfield.forms.fields import EnumChoiceField


class GenderEnum(enum.Enum):
    MALE = 1
    FEMALE = 2

    __labels__ = {
        MALE: "Male",
        FEMALE: "Female",
    }


class PersonForm(forms.Form):
    gender = EnumChoiceField(GenderEnum)

Rendering PersonForm in a template will generate a select-box with "Male" and "Female" as option labels for the gender field.

Local Development Environment

Make sure black and isort is installed in your env with pip install -e .[dev].

Before committing run make format to apply black and isort to all files.

More Repositories

1

djedi-cms

Django content management as it should be
CSS
81
star
2

django-bananas

Django extensions the monkey way
Python
65
star
3

django-viewlet

Render template parts with extended cache control.
Python
62
star
4

cobertura-action

GitHub Action to report cobertura coverage
JavaScript
51
star
5

django-formapi

Django API creation with signed requests utilizing forms for validation.
Python
34
star
6

socker

Redis pub/sub websocket proxy server, built on asyncio
Python
29
star
7

kapten

Auto deploy of Docker Swarm services
Python
18
star
8

content-io

Content flushed through cache, plugins and storage pipeline
Python
17
star
9

django-bananas.js

React admin frontend for Django
JavaScript
9
star
10

monkey-release-action

GitHub Action to validate and create GitHub Releases from pull requests
JavaScript
7
star
11

docker-nginx-streaming

Shell
6
star
12

python-email-reply-parser

Python port of https://github.com/github/email_reply_parser
Python
5
star
13

bpython

Yet another mirror of bitbucket.org/bobf/bpython
Python
5
star
14

pyparsing

Yet another mirror of pyparsing.svn.sourceforge.net
Python
4
star
15

bankid-sdk

A Python SDK for BankID
Python
4
star
16

partialize

Python partial on steroids
Python
4
star
17

reqlice

Python
3
star
18

bbq

Python
3
star
19

ec-paypal

PayPal Express Checkout
Python
3
star
20

python-ncs

NCS<->RGB color database for Python
Python
3
star
21

blues

Blues -- blueprints for Fabric
Python
2
star
22

socker-ios

An iOS socker client for handling multiple channels on a single websocket connection
Objective-C
2
star
23

django-traits

Python
2
star
24

zoomenhance

JavaScript
2
star
25

celery-deduplicate

Python
1
star
26

5monkeys.github.io

5monkeys.se
Svelte
1
star
27

refabric

Fabric blueprints
Python
1
star
28

docker-letsencrypt

Shell
1
star
29

docker-nginx

Shell
1
star
30

ansible-docker-role

This role will setup and configure a docker installation
Python
1
star