Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/flaeppe/django-choicefield
An enum field for Django models
https://github.com/flaeppe/django-choicefield
django enum enumfield python
Last synced: 20 days ago
JSON representation
An enum field for Django models
- Host: GitHub
- URL: https://github.com/flaeppe/django-choicefield
- Owner: flaeppe
- License: bsd-3-clause
- Created: 2022-09-18T20:40:36.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-10-24T19:50:39.000Z (23 days ago)
- Last Synced: 2024-10-26T02:17:37.236Z (21 days ago)
- Topics: django, enum, enumfield, python
- Language: Python
- Homepage: https://pypi.org/project/django-choicefield/
- Size: 119 KB
- Stars: 13
- Watchers: 4
- Forks: 1
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
Django ChoiceField
A Django model field that casts enum values to its enum type. Supports all enum types
shipped with Django and Python 3 native enum types.---
### Motivation
Have you also felt annoyed by having to convert
[Django's enumeration types](https://docs.djangoproject.com/en/dev/ref/models/fields/#enumeration-types)
_back_ to its type? Using tricks seen below to cast it.```python
class Suit(models.IntegerChoices):
DIAMOND = 1
SPADE = 2
HEART = 3
CLUB = 4class Card(models.Model):
suit_kind = models.IntegerField(choices=Suit.choices, db_column="suit")@property
def suit(self) -> Suit:
return Suit(self.suit_kind)
```This is what `django-choicefield` helps out with. While it additionally supports using
Python's native [enum.Enum](https://docs.python.org/3/library/enum.html) to express
column values.### Features
#### Using Django's enumeration types
```python
import choicefield
from django.db import modelsclass Suit(models.IntegerChoices):
DIAMOND = 1
SPADE = 2
HEART = 3
CLUB = 4class Card(models.Model):
suit = choicefield.ChoiceField(Suit)instance = Card.objects.create(suit=Suit.CLUB)
assert instance.suit is Suit.CLUB
```There's also support for Django's `models.TextChoices`.
#### Using Python's native enumeration
```python
import choicefield
from enum import Enum
from django.db import modelsclass Suit(int, Enum):
DIAMOND = 1
SPADE = 2
HEART = 3
CLUB = 4class Card(models.Model):
suit = choicefield.ChoiceField(Suit)instance = Card.objects.create(suit=Suit.DIAMOND)
assert instance.suit is Suit.DIAMOND
```#### Passing enum values
It's also possible to pass the _value_ of an enum, which will be converted to its
corresponding enum instance.```python
instance = Card(suit=2)
assert instance.suit is Suit.SPADE
instance.save()
assert instance.suit is Suit.SPADE
instance = Card.objects.get(suit=2)
assert instance.suit is Suit.SPADE
```### Getting stored database values
If you want to access the stored database values, without conversion to your enum type,
you can use the registered `__raw` transformer.```python
Card.objects.values("suit__raw")
#
```#### Getting unrecognized values from database
In case of e.g. a migration where an enum has changed by, say, removing a value. The
database could have values not recognized by the registered enum. Thus it could be
necessary to retrieve values _without_ casting them to an enum instance, as it'd raise
an error.It can be done using the `__raw` transformer while also sidestepping enum validation in
filter values by using
[`Value` expressions](https://docs.djangoproject.com/en/dev/ref/models/expressions/#value-expressions)```python
Card.objects.filter(suit=Value(1337)).values_list("suit__raw", flat=True)
#
```### Installation
Using `pip`
```console
$ pip install django-choicefield
```### Development
#### Running tests
Running the whole test matrix
```console
$ tox
```Setting up a development environment
```console
$ tox -e dev
```Running the test suite for one environment (non editable)
e.g. `Django==4.0.x` and `Python3.11`
```console
$ tox -e django40-py311
```#### Start a local example project
There are a couple of shortcut commands available using
[Taskfile](https://taskfile.dev/), for your convenience.e.g.
```console
$ task manage -- createsuperuser
$ task runserver
```After [installing Taskfile](https://taskfile.dev/installation/) you can run
`task --list-all` to find all available commands.### Compatibility
`django-choicefield` is tested according to the table below
| Django version | Python version |
| -------------- | -------------- |
| 5.0.x | ^3.10 |
| 4.2.x | ^3.9 |
| 4.1.x | ^3.9 |
| 4.0.x | ^3.9 |
| 3.2.x | ^3.9 |