Simple Runtime Choices for Django Models & Forms.
Project description
django-dbchoices
⚡ Simple Runtime Choices for Django Models & Forms
django-dbchoices provides a clean, lightweight way to manage dynamic choices in Django; backed by the database. It’s built for cases where valid choices depend on context—such as tenancy, environment, or configuration—and where hard-coded enums or frequent migrations become a bottleneck.
Key Features
- Plug-and-play integration: Works seamlessly with Django Models, Forms, Admin, DRF, and more.
- Runtime Evaluation: Choices are resolved dynamically when models and forms are loaded.
- Code-defined defaults: Declare default choices in code and easily sync them to the database.
- Built-in caching: Reduces database hits and keeps performance snappy.
- Swappable by design: Bring your own model to support multi-tenancy or attach extra metadata.
📦 Installation & Setup
pip install django-dbchoices
Add to your settings.py:
# settings.py
INSTALLED_APPS = [
# ...
'dbchoices',
]
Workflow
-
Migrate: Apply the package's initial migrations.
python manage.py migrate
-
Define Defaults: Register your required choices in your application's
AppConfig.ready()method:class MyAppConfig(AppConfig): name = 'myapp' def ready(self) -> None: from dbchoices.registry import ChoiceRegistry # Register choices using tuples ChoiceRegistry.register_defaults("Status", [ ("PENDING", "Booking Pending"), ("COMPLETE", "Booking Complete"), ("FAILED", "Booking Failed"), ]) # Or using TextChoices and/or Enums ChoiceRegistry.register_enum(StatusEnum)
-
Synchronize: Run the management command to push your code definitions into the database.
python manage.py dbchoices --sync
And you're all set! Your choices are now ready for use in models and forms.
Usage
Defining Models
Use the custom DynamicChoiceField to define the choice field(s) in the models. This field handles the necessary hooks
for validation and display.
# myapp/models.py
from dbchoices.fields import DynamicChoiceField
class Ticket(models.Model):
status = DynamicChoiceField(group_key='Status', default='PENDING')
Alternatively, if you wish to keep using standard Django fields, you can use DynamicChoiceValidator.
Note: This approach does not support automatic label/choice rendering in Django Admin/Forms.
# myapp/models.py
from django.db import models
from dbchoices.registry import ChoiceRegistry
class Ticket(models.Model):
status = models.CharField(
default='PENDING',
validators=[DynamicChoiceValidator(group_key='Status')],
)
API Access
The registry also provides helper methods for obtaining human-readable labels and models.TextChoices in your code logic.
Note: It is discouraged to use get_enum in typing-critical paths due to the ephemeral nature of runtime choices.
from dbchoices.registry import ChoiceRegistry
# Get the readable label
readable_status = ChoiceRegistry.get_label('ticket_status', 'in_progress')
# Get the Enum class for code logic
Status = ChoiceRegistry.get_enum('ticket_status')
if ticket.status == Status.CLOSED:
# ...
Settings
You can customize the behavior of django-dbchoices using the following settings in your settings.py:
# settings.py
# Cache timeout for dynamic choices (default: 1 hour)
DBCHOICES_CACHE_TIMEOUT = 3600
# Cache alias to use for caching dynamic choices (default: 'default')
DBCHOICES_CACHE_ALIAS = 'default'
# Whether to auto-invalidate cache on choice updates (default: True)
DBCHOICES_AUTO_INVALIDATE_CACHE = True
# Custom choice model path (default: 'dbchoices.Choice')
DBCHOICE_MODEL = 'myapp.CustomChoiceModel'
License
This project is licensed under the MIT License. See the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_dbchoices-0.1.0.tar.gz.
File metadata
- Download URL: django_dbchoices-0.1.0.tar.gz
- Upload date:
- Size: 10.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6bb813f2bae325f68f6d2d93f2038a9fe68b5c59305f73c9f81173bfce09b3c9
|
|
| MD5 |
8779dc78601f265dbb5aeb53d193488b
|
|
| BLAKE2b-256 |
7cd0c47ee0cfe668a4efc2d3d8f4bd936b4efa1a9f563bd62e3c710964fedae2
|
File details
Details for the file django_dbchoices-0.1.0-py3-none-any.whl.
File metadata
- Download URL: django_dbchoices-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15c935174432331cf910202caf8fcebac6fa8d1769a82c51642b2c863e6f37f0
|
|
| MD5 |
8c2647256ed528cbedc02b6da8af9215
|
|
| BLAKE2b-256 |
b86c5f97d9272a414ee58c5ec7abc2a91e8ce2742457099b31836bdd0ef6be5b
|