Better choices library for Django web framework
Project description
Django Better Choices
Better choices library for Django web framework.
Requirements
This library was written for Python 3.7+ and will not work in any earlier versions.
Install
pip install django-better-choices
Usage
To start defining better choices, you need first to import the Choices
class.
from django_better_choices import Choices
Class definition
The choices can be defined with overriding Choices
class.
class PageStatus(Choices):
CREATED = 'Created'
PENDING = Choices.Value('Pending', help_text='This set status to pending')
ON_HOLD = Choices.Value('On Hold', value='custom_on_hold')
VALID = Choices.Subset('CREATED', 'ON_HOLD')
INVISIBLE = Choices.Subset('PENDING', 'ON_HOLD')
class InternalStatus(Choices):
REVIEW = 'On Review'
@classmethod
def get_help_text(cls):
return tuple(
value.help_text
for value in cls.values()
if hasattr(value, 'help_text')
)
Overridden choices classes cannot be initialised to obtain a new instance. Initialisation will return a tuple of choice entries.
Inline definition
Alternatively, the choices can be defined dynamically by creating new Choices
object.
PageStatus = Choices('PageStatus', SUCCESS='Success', FAIL='Error')
The first
name
parameter ofChoices
constructor is optional and required only for better representation of the returned object.
Value accessors
You can access choices values using dot notation and with getattr()
.
value_created = PageStatus.CREATED
value_review = PageStatus.InternalStatus.REVIEW
value_on_hold = getattr(PageStatus, 'ON_HOLD')
Values and value parameters
Choices.Value
is a subclass of str
and equals to its value. In addition to display
parameter, other optional parameters can be specified in Choices.Value
constructor (see class definition example).
print( PageStatus.CREATED ) # 'created'
print( PageStatus.ON_HOLD ) # 'custom_on_hold'
print( PageStatus.PENDING.display ) # 'Pending'
print( PageStatus.PENDING.help_text ) # 'This set status to pending'
PageStatus.ON_HOLD == 'custom_on_hold' # True
PageStatus.CREATED == PageStatus.CREATED # True
Choices.Value
is an immutable string class, which object cannot be modified after initialisation. Native non-magicstr
methods can be overridden inChoices.Value
custom parameters.Choices.Value
behaves like a normal string, e.g.{'val1': 'something'}[CHOICES.VAL1] == 'something'
.
Search in choices
Search in choices is performed by value.
'created' in PageStatus # True
'custom_on_hold' in PageStatus # True
'on_hold' in PageStatus # False
value = PageStatus['custom_on_hold'] # Choices.Value
key, value = PageStatus.find('created') # ('CREATED', Choices.Value)
Search in subsets
Subsets are used to group several values together (see class definition example) and search by a specific value.
'custom_on_hold' in PageStatus.VALID # True
PageStatus.CREATED in PageStatus.VALID # True
Choices.Subset
is a subclass oftuple
, which is translated to inner choices class after definition. All internal or custom choices class methods or properties will be available in a subset class (see "Custom methods" section).
Extract subset
Subsets of choices can be dynamically extracted using a special extract()
method.
PageStatus.extract('CREATED', 'ON_HOLD') # ~= PageStatus.VALID
PageStatus.VALID.extract('ON_HOLD') # Choices('PageStatus.VALID.Subset', ON_HOLD)
Choices iteration
Choices class implements __iter__
magic method, hence choices are iterable that yield choice entries (i.e. (value, display)
). Methods items()
, keys()
and values()
can be used to return tuples of keys and values combinations.
for value, display in PageStatus:
print( value, display )
for key, value in PageStatus.items():
print( key, value, value.display )
for key in PageStatus.keys():
print( key )
for value in PageStatus.values():
print( value, value.display, value.__choice_entry__ )
Additional displays()
method is provided for choices and subsets to extract values display strings.
for display in PageStatus.displays():
print( display )
for display in PageStatus.SUBSET.displays():
print( display )
Set operations
Choices class supports standard set operations: union (|
), intersection (&
), difference (-
), and symmetric difference (^
).
PageStatus.VALID | PageStatus.INVISIBLE # Choices(CREATED, ON_HOLD, PENDING)
PageStatus.VALID & PageStatus.INVISIBLE # Choices(ON_HOLD)
PageStatus.VALID - PageStatus.INVISIBLE # Choices(CREATED)
PageStatus.VALID ^ PageStatus.INVISIBLE # Choices(CREATED, PENDING)
Custom methods
All custom choices class methods or properties (non-values) will be available in all subsets.
PageStatus.get_help_text()
PageStatus.VALID.get_help_text()
PageStatus.extract('PENDING', 'ON_HOLD').get_help_text()
PageStatus.VALID.extract('ON_HOLD').get_help_text()
Django model fields
Better choices are not different to the original Django choices in terms of usage in models.
class Page(models.Model):
status = models.CharField(choices=PageStatus, default=PageStatus.CREATED)
Better choices are fully supported by Django migrations.
Saving choices on models
Better choices are compatible with standard Django models manipulation.
page = Page.objects.get(pk=1)
page.status = PageStatus.PENDING
page.save()
Tests
Run python tests.py
for testing.
License
Library is available under the MIT license. The included LICENSE file describes this in detail.
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
Hashes for django-better-choices-1.13.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | df11cbff5896d2a7280b1a08e726ed64d604cadb233b9d20dc791e6f383128ea |
|
MD5 | 853691bc6b595ad946272ae54d7646ae |
|
BLAKE2b-256 | 6e712e3e61c3dc7540f81e4b2f0b4c0edc8879cd22b6f5017a0bd45fcb314821 |
Hashes for django_better_choices-1.13-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2e481828a2a8b5b10e48ff852f1a7b96b2147e5534f4fbed500040e4fa4f60ef |
|
MD5 | 22ecea3b4e8c20ff231dcf047cab04ee |
|
BLAKE2b-256 | e292f0a138b7438381db5d876f93fe481789d8e680e1c8eefdb0e8b5b27af84b |