Use Flags (BitFields)¶
Python supports bit fields through the
enum.Flag
extension to enum.Enum
.
These enumerations are fully supported and will render as multi select form fields by default. For example:
from enum import IntFlag
from django_enum import EnumField
from django.db import models
class Group(models.Model):
class Permissions(IntFlag):
# fmt: off
READ = 1 << 0
WRITE = 1 << 1
EXECUTE = 1 << 2
# IntFlags can have composite values!
RWX = READ | WRITE | EXECUTE
# fmt: on
permissions = EnumField(Permissions)
assert Group.Permissions.READ in group1.permissions
assert Group.Permissions.WRITE not in group1.permissions
assert Group.Permissions.EXECUTE in group1.permissions
assert Group.Permissions.READ in group2.permissions
assert Group.Permissions.WRITE in group2.permissions
assert Group.Permissions.EXECUTE in group2.permissions
assert group2.permissions is Group.Permissions.RWX
Two new field lookups are provided for flag enumerations: has_any and has_all.
has_any¶
The has_any lookup will return any object that has at least one of the flags in the referenced enumeration. For example:
# this will return both group1 and group2
read_or_write = Group.objects.filter(
permissions__has_any=Group.Permissions.READ | Group.Permissions.WRITE
)
assert (
group1 in read_or_write and
group2 in read_or_write
)
has_all¶
The has_all lookup will return any object that has at least all of the flags in the referenced enumeration. For example:
# this will return only group2
read_and_write = Group.objects.filter(
permissions__has_all=Group.Permissions.READ | Group.Permissions.WRITE
)
assert (
group1 not in read_and_write and
group2 in read_and_write
)
There are performance considerations when using a bit mask like a Flag enumeration instead of multiple boolean columns. See flag performance for discussion and benchmarks.
Flags with more than 64 bits¶
Flag enumerations of arbitrary size are supported, however if the enum has more than 64 flags it
will be stored as a BinaryField
. It is therefore strongly recommended to
keep your enum.IntFlag
enumerations at 64 bits or less.