django-metachoices


Namedjango-metachoices JSON
Version 0.1.6 PyPI version JSON
download
home_pageNone
SummaryA Django field extension that allows choices to have rich metadata beyond the standard (value, display) tuple
upload_time2025-07-13 15:06:57
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseNone
keywords django choices metadata fields
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Django Meta Choices

[![PyPI version](https://badge.fury.io/py/django-metachoices.svg)](https://badge.fury.io/py/django-metachoices)
[![Python versions](https://img.shields.io/pypi/pyversions/django-metachoices.svg)](https://pypi.org/project/django-metachoices/)
[![Django versions](https://img.shields.io/pypi/djversions/django-metachoices.svg)](https://pypi.org/project/django-metachoices/)
[![CI](https://github.com/luqmaansu/django-metachoices/workflows/CI/badge.svg)](https://github.com/luqmaansu/django-metachoices/actions)
[![codecov](https://codecov.io/gh/luqmaansu/django-metachoices/branch/main/graph/badge.svg)](https://codecov.io/gh/luqmaansu/django-metachoices)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A Django field extension that allows choices to have rich metadata beyond the standard (value, display) tuple.

## Overview

Django's standard choice fields only support a simple key-value mapping. This package extends that functionality to allow arbitrary metadata for each choice, which can be accessed through dynamically generated getter methods.

## Example

### Without metachoices

```python

STATUS_CHOICES = {
    "ACTIVE": "Active",
    "INACTIVE": "Inactive",
}

class User(models.Model):
    name = models.CharField(max_length=100)
    status = models.CharField(choices=STATUS_CHOICES) # The normal CharField with choices


# Usage
user = User.objects.create(name="John", status="ACTIVE")

# Access choice data as usual
print(user.status)                    # The database stored value, "ACTIVE"
print(user.get_status_display())      # The human-readable display value, "Active"

```


### With metachoices

```python
from django.db import models
from metachoices import MetaChoiceField

# Define choices with rich metadata
STATUS_CHOICES = {
    "ACTIVE": {
        "display": "Active",
        "color": "#28a745",
        "description": "User is active and can access the system",
        "icon": "check-circle",
        "priority": 1,
    },
    "INACTIVE": {
        "display": "Inactive", 
        "color": "#6c757d",
        "description": "User is inactive and cannot access the system",
        "icon": "x-circle",
        "priority": 2,
    },
}

class User(models.Model):
    name = models.CharField(max_length=100)
    status = MetaChoiceField(choices=STATUS_CHOICES) # Use MetaChoiceField with choices instead of CharField

# Usage
user = User.objects.create(name="John", status="ACTIVE")

# Access choice data as usual
print(user.status)                    # The database stored value, "ACTIVE"
print(user.get_status_display())      # The human-readable display value, "Active"

# With richer capabilities!
print(user.get_status_color())        # "#28a745"
print(user.get_status_description())  # "User is active and can access the system"
print(user.get_status_icon())         # "check-circle"
print(user.get_status_priority())     # 1
```

## Features

- **Rich Metadata**: Add any number of attributes to your choices (description, url, icon, priority, etc.)
- **Dynamic Getters**: Automatically generates `get_<field>_<attribute>()` methods for all metadata attributes
- **Django Compatible**: Works seamlessly with Django's existing choice field functionality
- **Admin Integration**: Fully compatible with Django admin
- **Type Safe**: Validates that field values are valid choice keys
- **Auto-Detection**: Automatically detects whether to use CharField or IntegerField based on choice keys

## Installation

Install from PyPI:

```bash
pip install django-metachoices
# or with UV (recommended)
uv add django-metachoices
```

That's it! No need to add anything to `INSTALLED_APPS` - just import and use the field directly in your models.

## Requirements

- **Python**: 3.10+
- **Django**: 4.2+



## Compatibility

This package is tested with:
- **Python**: 3.10, 3.11, 3.12, 3.13
- **Django**: 4.2 (LTS), 5.0, 5.1, 5.2

For local testing across multiple versions, we recommend using `tox`:

```bash
# Install development dependencies
uv add --group dev tox

# Test specific combinations
uv run tox -e py310-django42    # Python 3.10 + Django 4.2
uv run tox -e py312-django51    # Python 3.12 + Django 5.1
uv run tox -e py313-django52    # Python 3.13 + Django 5.2

# Test with multiple Python versions (requires installing them first)
uv python install 3.10 3.11 3.12 3.13
uv run tox
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "django-metachoices",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": "Luqmaan <luqmaansu@gmail.com>",
    "keywords": "django, choices, metadata, fields",
    "author": null,
    "author_email": "Luqmaan <luqmaansu@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/8d/4d/223897d71b7258ea3a14a8654a468e614215d35327ed467c32751c842a44/django_metachoices-0.1.6.tar.gz",
    "platform": null,
    "description": "# Django Meta Choices\r\n\r\n[![PyPI version](https://badge.fury.io/py/django-metachoices.svg)](https://badge.fury.io/py/django-metachoices)\r\n[![Python versions](https://img.shields.io/pypi/pyversions/django-metachoices.svg)](https://pypi.org/project/django-metachoices/)\r\n[![Django versions](https://img.shields.io/pypi/djversions/django-metachoices.svg)](https://pypi.org/project/django-metachoices/)\r\n[![CI](https://github.com/luqmaansu/django-metachoices/workflows/CI/badge.svg)](https://github.com/luqmaansu/django-metachoices/actions)\r\n[![codecov](https://codecov.io/gh/luqmaansu/django-metachoices/branch/main/graph/badge.svg)](https://codecov.io/gh/luqmaansu/django-metachoices)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\r\n\r\nA Django field extension that allows choices to have rich metadata beyond the standard (value, display) tuple.\r\n\r\n## Overview\r\n\r\nDjango's standard choice fields only support a simple key-value mapping. This package extends that functionality to allow arbitrary metadata for each choice, which can be accessed through dynamically generated getter methods.\r\n\r\n## Example\r\n\r\n### Without metachoices\r\n\r\n```python\r\n\r\nSTATUS_CHOICES = {\r\n    \"ACTIVE\": \"Active\",\r\n    \"INACTIVE\": \"Inactive\",\r\n}\r\n\r\nclass User(models.Model):\r\n    name = models.CharField(max_length=100)\r\n    status = models.CharField(choices=STATUS_CHOICES) # The normal CharField with choices\r\n\r\n\r\n# Usage\r\nuser = User.objects.create(name=\"John\", status=\"ACTIVE\")\r\n\r\n# Access choice data as usual\r\nprint(user.status)                    # The database stored value, \"ACTIVE\"\r\nprint(user.get_status_display())      # The human-readable display value, \"Active\"\r\n\r\n```\r\n\r\n\r\n### With metachoices\r\n\r\n```python\r\nfrom django.db import models\r\nfrom metachoices import MetaChoiceField\r\n\r\n# Define choices with rich metadata\r\nSTATUS_CHOICES = {\r\n    \"ACTIVE\": {\r\n        \"display\": \"Active\",\r\n        \"color\": \"#28a745\",\r\n        \"description\": \"User is active and can access the system\",\r\n        \"icon\": \"check-circle\",\r\n        \"priority\": 1,\r\n    },\r\n    \"INACTIVE\": {\r\n        \"display\": \"Inactive\", \r\n        \"color\": \"#6c757d\",\r\n        \"description\": \"User is inactive and cannot access the system\",\r\n        \"icon\": \"x-circle\",\r\n        \"priority\": 2,\r\n    },\r\n}\r\n\r\nclass User(models.Model):\r\n    name = models.CharField(max_length=100)\r\n    status = MetaChoiceField(choices=STATUS_CHOICES) # Use MetaChoiceField with choices instead of CharField\r\n\r\n# Usage\r\nuser = User.objects.create(name=\"John\", status=\"ACTIVE\")\r\n\r\n# Access choice data as usual\r\nprint(user.status)                    # The database stored value, \"ACTIVE\"\r\nprint(user.get_status_display())      # The human-readable display value, \"Active\"\r\n\r\n# With richer capabilities!\r\nprint(user.get_status_color())        # \"#28a745\"\r\nprint(user.get_status_description())  # \"User is active and can access the system\"\r\nprint(user.get_status_icon())         # \"check-circle\"\r\nprint(user.get_status_priority())     # 1\r\n```\r\n\r\n## Features\r\n\r\n- **Rich Metadata**: Add any number of attributes to your choices (description, url, icon, priority, etc.)\r\n- **Dynamic Getters**: Automatically generates `get_<field>_<attribute>()` methods for all metadata attributes\r\n- **Django Compatible**: Works seamlessly with Django's existing choice field functionality\r\n- **Admin Integration**: Fully compatible with Django admin\r\n- **Type Safe**: Validates that field values are valid choice keys\r\n- **Auto-Detection**: Automatically detects whether to use CharField or IntegerField based on choice keys\r\n\r\n## Installation\r\n\r\nInstall from PyPI:\r\n\r\n```bash\r\npip install django-metachoices\r\n# or with UV (recommended)\r\nuv add django-metachoices\r\n```\r\n\r\nThat's it! No need to add anything to `INSTALLED_APPS` - just import and use the field directly in your models.\r\n\r\n## Requirements\r\n\r\n- **Python**: 3.10+\r\n- **Django**: 4.2+\r\n\r\n\r\n\r\n## Compatibility\r\n\r\nThis package is tested with:\r\n- **Python**: 3.10, 3.11, 3.12, 3.13\r\n- **Django**: 4.2 (LTS), 5.0, 5.1, 5.2\r\n\r\nFor local testing across multiple versions, we recommend using `tox`:\r\n\r\n```bash\r\n# Install development dependencies\r\nuv add --group dev tox\r\n\r\n# Test specific combinations\r\nuv run tox -e py310-django42    # Python 3.10 + Django 4.2\r\nuv run tox -e py312-django51    # Python 3.12 + Django 5.1\r\nuv run tox -e py313-django52    # Python 3.13 + Django 5.2\r\n\r\n# Test with multiple Python versions (requires installing them first)\r\nuv python install 3.10 3.11 3.12 3.13\r\nuv run tox\r\n```\r\n\r\n## Contributing\r\n\r\nContributions are welcome! Please feel free to submit a Pull Request.\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. \r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A Django field extension that allows choices to have rich metadata beyond the standard (value, display) tuple",
    "version": "0.1.6",
    "project_urls": {
        "Bug Tracker": "https://github.com/luqmaansu/django-metachoices/issues",
        "Documentation": "https://github.com/luqmaansu/django-metachoices#readme",
        "Homepage": "https://github.com/luqmaansu/django-metachoices",
        "Repository": "https://github.com/luqmaansu/django-metachoices"
    },
    "split_keywords": [
        "django",
        " choices",
        " metadata",
        " fields"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f2ff5be7b2f002060181a61c4f7c04512c6b10d617105b4d14e3f9a343ff8641",
                "md5": "f503522fddc374e3625bcbb34d98a73d",
                "sha256": "0c61fea87d3d9bacba0b40e75963cb1b74868926fdf6b314311a8327573e17f5"
            },
            "downloads": -1,
            "filename": "django_metachoices-0.1.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f503522fddc374e3625bcbb34d98a73d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 10246,
            "upload_time": "2025-07-13T15:06:54",
            "upload_time_iso_8601": "2025-07-13T15:06:54.020358Z",
            "url": "https://files.pythonhosted.org/packages/f2/ff/5be7b2f002060181a61c4f7c04512c6b10d617105b4d14e3f9a343ff8641/django_metachoices-0.1.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8d4d223897d71b7258ea3a14a8654a468e614215d35327ed467c32751c842a44",
                "md5": "90682b85701e4a22c86e893c73306fe6",
                "sha256": "0fc738b96d8bc9140a0c67a53f54d00ba22cb2e4c9105d4c5eb3012cd523da8a"
            },
            "downloads": -1,
            "filename": "django_metachoices-0.1.6.tar.gz",
            "has_sig": false,
            "md5_digest": "90682b85701e4a22c86e893c73306fe6",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 10955,
            "upload_time": "2025-07-13T15:06:57",
            "upload_time_iso_8601": "2025-07-13T15:06:57.007083Z",
            "url": "https://files.pythonhosted.org/packages/8d/4d/223897d71b7258ea3a14a8654a468e614215d35327ed467c32751c842a44/django_metachoices-0.1.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-13 15:06:57",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "luqmaansu",
    "github_project": "django-metachoices",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "django-metachoices"
}
        
Elapsed time: 1.68995s