Skip to main content

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

  1. Migrate: Apply the package's initial migrations.

    python manage.py migrate
    
  2. 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)
    
  3. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_dbchoices-0.1.0.tar.gz (10.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_dbchoices-0.1.0-py3-none-any.whl (15.6 kB view details)

Uploaded Python 3

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

Hashes for django_dbchoices-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6bb813f2bae325f68f6d2d93f2038a9fe68b5c59305f73c9f81173bfce09b3c9
MD5 8779dc78601f265dbb5aeb53d193488b
BLAKE2b-256 7cd0c47ee0cfe668a4efc2d3d8f4bd936b4efa1a9f563bd62e3c710964fedae2

See more details on using hashes here.

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

Hashes for django_dbchoices-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 15c935174432331cf910202caf8fcebac6fa8d1769a82c51642b2c863e6f37f0
MD5 8c2647256ed528cbedc02b6da8af9215
BLAKE2b-256 b86c5f97d9272a414ee58c5ec7abc2a91e8ce2742457099b31836bdd0ef6be5b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page