A Django field extension that allows choices to have rich metadata beyond the standard (value, display) tuple
Project description
Django Meta Choices
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, accessible through both:
- Dot notation (v0.2+):
obj.status.color - Getter methods (v0.1 compatible):
obj.get_status_color()
Version 0.2 introduces a cleaner, class-based API while maintaining full backward compatibility with v0.1.
Example
Without metachoices
STATUS_CHOICES = {
"ACTIVE": "Active",
"INACTIVE": "Inactive",
}
class User(models.Model):
name = models.CharField(max_length=100)
status = models.CharField(choices=STATUS_CHOICES)
# Usage
user = User.objects.create(name="John", status="ACTIVE")
print(user.status) # "ACTIVE"
print(user.get_status_display()) # "Active"
With metachoices (v0.2 - Recommended)
from django.db import models
from metachoices import MetaChoices, MetaChoiceFieldV2
# Define choices as a class with metadata
class StatusChoices(MetaChoices):
ACTIVE = {
"value": "active",
"display": "Active",
"color": "#28a745",
"description": "User is active and can access the system",
"icon": "check-circle",
"priority": 1,
}
INACTIVE = {
"value": "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 = MetaChoiceFieldV2(StatusChoices, max_length=20)
# Usage - New dot notation API (v0.2)
user = User.objects.create(name="John", status="active")
print(user.status) # "active" (behaves like a string)
print(user.status == "active") # True
print(user.status.display) # "Active"
print(user.status.color) # "#28a745"
print(user.status.description) # "User is active and can access the system"
print(user.status.icon) # "check-circle"
print(user.status.priority) # 1
# Backward compatible - old getter methods still work!
print(user.get_status_display()) # "Active"
print(user.get_status_color()) # "#28a745"
print(user.get_status_description()) # "User is active and can access the system"
With metachoices (v0.1 - Dictionary Format)
from django.db import models
from metachoices import MetaChoiceField
# Define choices with rich metadata (v0.1 style)
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)
# Usage
user = User.objects.create(name="John", status="ACTIVE")
print(user.status) # "ACTIVE"
print(user.get_status_display()) # "Active"
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.)
- Clean Dot Notation (v0.2): Access metadata with intuitive
obj.field.attributesyntax - Backward Compatible: v0.1 getter methods (
get_<field>_<attr>()) still work in v0.2 - Class-Based Choices (v0.2): Define choices as Python classes for better IDE support
- 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 values
- Python 3.13 Safe: Explicitly handles Windows + Python 3.13 compatibility issues
Installation
Install from PyPI:
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.
API Comparison
| Feature | v0.1 (Dictionary) | v0.2 (Class-Based) |
|---|---|---|
| Choice Definition | {"KEY": {...}} |
class MyChoices(MetaChoices) |
| Field Import | MetaChoiceField |
MetaChoiceFieldV2 |
| Access Metadata | obj.get_field_attr() |
obj.field.attr ✨ |
| Backward Compatible | N/A | ✅ Old methods still work |
| IDE Autocomplete | Limited | Better with dataclasses |
| Type Safety | Runtime | Runtime + better hints |
Recommendation: Use v0.2 for new projects. v0.1 remains fully supported.
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:
# 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 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
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_metachoices-0.2.0.tar.gz.
File metadata
- Download URL: django_metachoices-0.2.0.tar.gz
- Upload date:
- Size: 16.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
676a3151c8c6c4f2da3c37563c5430327b4442128bb1b6ec23789250a83c8dd9
|
|
| MD5 |
b04f6989737792bda33ecb66319f750f
|
|
| BLAKE2b-256 |
f796827727a455263c69c0974c65ca2d44bb8b03d510068b8668cd87710b05b4
|
File details
Details for the file django_metachoices-0.2.0-py3-none-any.whl.
File metadata
- Download URL: django_metachoices-0.2.0-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a0d586e8f16d3003006bde6a89ee59664d5b1a6607a62a862efa4bf9762306a
|
|
| MD5 |
409523d641d2feecd9fc439cf6f8dbf2
|
|
| BLAKE2b-256 |
9852e6385efc0fce472c7c1e6faec1fdce54988c01ad41b02bc7426faf471bb6
|