extended_choices.choices module¶
Provides a Choices class to help using “choices” in Django fields.
The aim is to replace:
STATE_ONLINE = 1
STATE_DRAFT = 2
STATE_OFFLINE = 3
STATE_CHOICES = (
(STATE_ONLINE, 'Online'),
(STATE_DRAFT, 'Draft'),
(STATE_OFFLINE, 'Offline'),
)
STATE_DICT = dict(STATE_CHOICES)
class Content(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
state = models.PositiveSmallIntegerField(choices=STATE_CHOICES, default=STATE_DRAFT)
def __unicode__(self):
return 'Content "%s" (state=%s)' % (self.title, STATE_DICT[self.state])
print(Content.objects.filter(state=STATE_ONLINE))
By this:
from extended_choices import Choices
STATES = Choices(
('ONLINE', 1, 'Online'),
('DRAFT', 2, 'Draft'),
('OFFLINE', 3, 'Offline'),
)
class Content(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
state = models.PositiveSmallIntegerField(choices=STATES, default=STATES.DRAFT)
def __unicode__(self):
return 'Content "%s" (state=%s)' % (self.title, STATES.for_value(self.state).display)
print(Content.objects.filter(state=STATES.ONLINE))
Notes
The documentation format in this file is numpydoc.
-
class
extended_choices.choices.Choices(*choices, **kwargs)[source]¶ Bases:
listHelper class for choices fields in Django
A choice entry has three representation: constant name, value and display name). So
Choicestakes list of such tuples.It’s easy to get the constant, value or display name given one of these value. See in example.
Parameters: - *choices (list of tuples) –
It’s the list of tuples to add to the
Choicesinstance, each tuple having three entries: the constant name, the value, the display name.A dict could be added as a 4th entry in the tuple to allow setting arbitrary arguments to the final
ChoiceEntrycreated for this choice tuple. - name (string, optional) – If set, a subset will be created containing all the constants. It could be used if you
construct your
Choicesinstance with many calls toadd_choices. - dict_class (type, optional) –
dictby default, it’s the dict class to use to create dictionaries (constants,valuesanddisplays. Could be set for example toOrderedDict(you can useOrderedChoicesthat is a simple subclass usingOrderedDict.
Example
Start by declaring your
Choices:>>> ALIGNMENTS = Choices( ... ('BAD', 10, 'bad'), ... ('NEUTRAL', 20, 'neutral'), ... ('CHAOTIC_GOOD', 30, 'chaotic good'), ... ('GOOD', 40, 'good'), ... dict_class=OrderedDict ... )
Then you can use it in a django field, Notice its usage in
choicesanddefault:>>> from django.conf import settings >>> try: ... settings.configure(DATABASE_ENGINE='sqlite3') ... except: pass >>> from django.db.models import IntegerField >>> field = IntegerField(choices=ALIGNMENTS, # use ``ALIGNMENTS`` or ``ALIGNMENTS.choices``. ... default=ALIGNMENTS.NEUTRAL)
The
Choicesreturns a list as expected by django:>>> ALIGNMENTS == ((10, 'bad'), (20, 'neutral'), (30, 'chaotic good'), (40, 'good')) True
But represents it with the constants:
>>> repr(ALIGNMENTS) "[('BAD', 10, 'bad'), ('NEUTRAL', 20, 'neutral'), ('CHAOTIC_GOOD', 30, 'chaotic good'), ('GOOD', 40, 'good')]"
Use
choiceswhich is a simple list to represent it as such:>>> ALIGNMENTS.choices ((10, 'bad'), (20, 'neutral'), (30, 'chaotic good'), (40, 'good'))
And you can access value by their constant, or as you want:
>>> ALIGNMENTS.BAD 10 >>> ALIGNMENTS.BAD.display 'bad' >>> 40 in ALIGNMENTS True >>> ALIGNMENTS.has_constant('BAD') True >>> ALIGNMENTS.has_value(20) True >>> ALIGNMENTS.has_display('good') True >>> ALIGNMENTS.for_value(10) ('BAD', 10, 'bad') >>> ALIGNMENTS.for_value(10).constant 'BAD' >>> ALIGNMENTS.for_display('good').value 40 >>> ALIGNMENTS.for_constant('NEUTRAL').display 'neutral' >>> ALIGNMENTS.constants OrderedDict([('BAD', ('BAD', 10, 'bad')), ('NEUTRAL', ('NEUTRAL', 20, 'neutral')), ('CHAOTIC_GOOD', ('CHAOTIC_GOOD', 30, 'chaotic good')), ('GOOD', ('GOOD', 40, 'good'))]) >>> ALIGNMENTS.values OrderedDict([(10, ('BAD', 10, 'bad')), (20, ('NEUTRAL', 20, 'neutral')), (30, ('CHAOTIC_GOOD', 30, 'chaotic good')), (40, ('GOOD', 40, 'good'))]) >>> ALIGNMENTS.displays OrderedDict([('bad', ('BAD', 10, 'bad')), ('neutral', ('NEUTRAL', 20, 'neutral')), ('chaotic good', ('CHAOTIC_GOOD', 30, 'chaotic good')), ('good', ('GOOD', 40, 'good'))])
You can create subsets of choices:
>>> ALIGNMENTS.add_subset('WESTERN',('BAD', 'GOOD')) >>> ALIGNMENTS.WESTERN.choices ((10, 'bad'), (40, 'good')) >>> ALIGNMENTS.BAD in ALIGNMENTS.WESTERN True >>> ALIGNMENTS.NEUTRAL in ALIGNMENTS.WESTERN False
To use it in another field (only the values in the subset will be available), or for checks:
>>> def is_western(value): ... return value in ALIGNMENTS.WESTERN >>> is_western(40) True
-
ChoiceEntryClass¶ alias of
extended_choices.helpers.ChoiceEntry
-
add_choices(*choices, **kwargs)[source]¶ Add some choices to the current
Choicesinstance.The given choices will be added to the existing choices. If a
nameattribute is passed, a new subset will be created with all the given choices.Note that it’s not possible to add new choices to a subset.
Parameters: - *choices (list of tuples) –
It’s the list of tuples to add to the
Choicesinstance, each tuple having three entries: the constant name, the value, the display name.A dict could be added as a 4th entry in the tuple to allow setting arbitrary arguments to the final
ChoiceEntrycreated for this choice tuple.If the first entry of
*choicesis a string, then it will be used as a name for a new subset that will contain all the given choices. - **kwargs (dict) –
- name : string
- Instead of using the first entry of the
*choicesto pass a name of a subset to create, you can pass it via thenamenamed argument.
Example
>>> MY_CHOICES = Choices() >>> MY_CHOICES.add_choices(('ZERO', 0, 'zero')) >>> MY_CHOICES [('ZERO', 0, 'zero')] >>> MY_CHOICES.add_choices('SMALL', ('ONE', 1, 'one'), ('TWO', 2, 'two')) >>> MY_CHOICES [('ZERO', 0, 'zero'), ('ONE', 1, 'one'), ('TWO', 2, 'two')] >>> MY_CHOICES.SMALL [('ONE', 1, 'one'), ('TWO', 2, 'two')] >>> MY_CHOICES.add_choices(('THREE', 3, 'three'), ('FOUR', 4, 'four'), name='BIG') >>> MY_CHOICES [('ZERO', 0, 'zero'), ('ONE', 1, 'one'), ('TWO', 2, 'two'), ('THREE', 3, 'three'), ('FOUR', 4, 'four')] >>> MY_CHOICES.BIG [('THREE', 3, 'three'), ('FOUR', 4, 'four')]
Raises: - RuntimeError – When the
Choicesinstance is marked as not mutable, which is the case for subsets. - ValueError –
- if the subset name is defined as first argument and as named argument. * if some constants have the same name or the same value. * if at least one constant or value already exists in the instance.
- *choices (list of tuples) –
-
add_subset(name, constants)[source]¶ Add a subset of entries under a defined name.
This allow to defined a “sub choice” if a django field need to not have the whole choice available.
The sub-choice is a new
Choicesinstance, with only the wanted the constant from the mainChoices(each “choice entry” in the subset is shared from the mainChoices) The sub-choice is accessible from the mainChoicesby an attribute having the given name.Parameters: - name (string) – Name of the attribute that will old the new
Choicesinstance. - constants (list or tuple) – List of the constants name of this
Choicesobject to make available in the subset.
Returns: The newly created subset, which is a
ChoicesobjectReturn type: Example
>>> STATES = Choices( ... ('ONLINE', 1, 'Online'), ... ('DRAFT', 2, 'Draft'), ... ('OFFLINE', 3, 'Offline'), ... ) >>> STATES [('ONLINE', 1, 'Online'), ('DRAFT', 2, 'Draft'), ('OFFLINE', 3, 'Offline')] >>> STATES.add_subset('NOT_ONLINE', ('DRAFT', 'OFFLINE',)) >>> STATES.NOT_ONLINE [('DRAFT', 2, 'Draft'), ('OFFLINE', 3, 'Offline')] >>> STATES.NOT_ONLINE.DRAFT 2 >>> STATES.NOT_ONLINE.for_constant('DRAFT') is STATES.for_constant('DRAFT') True >>> STATES.NOT_ONLINE.ONLINE Traceback (most recent call last): ... AttributeError: 'Choices' object has no attribute 'ONLINE'
Raises: ValueError – - If
nameis already an attribute of theChoicesinstance. * If a constant is not defined as a constant in theChoicesinstance.
- name (string) – Name of the attribute that will old the new
-
choices¶ Property that returns a tuple formatted as expected by Django.
Example
>>> MY_CHOICES = Choices(('FOO', 1, 'foo'), ('BAR', 2, 'bar')) >>> MY_CHOICES.choices ((1, 'foo'), (2, 'bar'))
-
extract_subset(*constants)[source]¶ Create a subset of entries
This subset is a new
Choicesinstance, with only the wanted constants from the mainChoices(each “choice entry” in the subset is shared from the mainChoices)Parameters: *constants (list) – The constants names of this Choicesobject to make available in the subset.Returns: The newly created subset, which is a ChoicesobjectReturn type: Choices Example
>>> STATES = Choices( ... ('ONLINE', 1, 'Online'), ... ('DRAFT', 2, 'Draft'), ... ('OFFLINE', 3, 'Offline'), ... ) >>> STATES [('ONLINE', 1, 'Online'), ('DRAFT', 2, 'Draft'), ('OFFLINE', 3, 'Offline')] >>> subset = STATES.extract_subset('DRAFT', 'OFFLINE') >>> subset [('DRAFT', 2, 'Draft'), ('OFFLINE', 3, 'Offline')] >>> subset.DRAFT 2 >>> subset.for_constant('DRAFT') is STATES.for_constant('DRAFT') True >>> subset.ONLINE Traceback (most recent call last): ... AttributeError: 'Choices' object has no attribute 'ONLINE'
Raises: ValueError – If a constant is not defined as a constant in the Choicesinstance.
-
for_constant(constant)[source]¶ Returns the
ChoiceEntryfor the given constant.Parameters: constant (string) – Name of the constant for which we want the choice entry. Returns: The instance of ChoiceEntryfor the given constant.Return type: ChoiceEntry Raises: KeyError – If the constant is not an existing one. Example
>>> MY_CHOICES = Choices(('FOO', 1, 'foo'), ('BAR', 2, 'bar')) >>> MY_CHOICES.for_constant('FOO') ('FOO', 1, 'foo') >>> MY_CHOICES.for_constant('FOO').value 1 >>> MY_CHOICES.for_constant('QUX') Traceback (most recent call last): ... KeyError: 'QUX'
-
for_display(display)[source]¶ Returns the
ChoiceEntryfor the given display name.Parameters: display (string) – Display name for which we want the choice entry. Returns: The instance of ChoiceEntryfor the given display name.Return type: ChoiceEntry Raises: KeyError – If the display name is not an existing one. Example
>>> MY_CHOICES = Choices(('FOO', 1, 'foo'), ('BAR', 2, 'bar')) >>> MY_CHOICES.for_display('foo') ('FOO', 1, 'foo') >>> MY_CHOICES.for_display('foo').constant 'FOO' >>> MY_CHOICES.for_display('qux') Traceback (most recent call last): ... KeyError: 'qux'
-
for_value(value)[source]¶ Returns the
ChoiceEntryfor the given value.Parameters: value – Value for which we want the choice entry. Returns: The instance of ChoiceEntryfor the given value.Return type: ChoiceEntry Raises: KeyError – If the value is not an existing one. Example
>>> MY_CHOICES = Choices(('FOO', 1, 'foo'), ('BAR', 2, 'bar')) >>> MY_CHOICES.for_value(1) ('FOO', 1, 'foo') >>> MY_CHOICES.for_value(1).display 'foo' >>> MY_CHOICES.for_value(3) Traceback (most recent call last): ... KeyError: 3
-
has_constant(constant)[source]¶ Check if the current
Choicesobject has the given constant.Parameters: constant (string) – Name of the constant we want to check.. Returns: Trueif the constant is present,Falseotherwise.Return type: boolean Example
>>> MY_CHOICES = Choices(('FOO', 1, 'foo'), ('BAR', 2, 'bar')) >>> MY_CHOICES.has_constant('FOO') True >>> MY_CHOICES.has_constant('QUX') False
-
has_display(display)[source]¶ Check if the current
Choicesobject has the given display name.Parameters: display (string) – Display name we want to check.. Returns: Trueif the display name is present,Falseotherwise.Return type: boolean Example
>>> MY_CHOICES = Choices(('FOO', 1, 'foo'), ('BAR', 2, 'bar')) >>> MY_CHOICES.has_display('foo') True >>> MY_CHOICES.has_display('qux') False
-
has_value(value)[source]¶ Check if the current
Choicesobject has the given value.Parameters: value – Value we want to check. Returns: Trueif the value is present,Falseotherwise.Return type: boolean Example
>>> MY_CHOICES = Choices(('FOO', 1, 'foo'), ('BAR', 2, 'bar')) >>> MY_CHOICES.has_value(1) True >>> MY_CHOICES.has_value(3) False
- *choices (list of tuples) –
-
class
extended_choices.choices.OrderedChoices(*choices, **kwargs)[source]¶ Bases:
extended_choices.choices.ChoicesSimple subclass of
ChoicesusingOrderedDictasdict_classExample
Start by declaring your
Choices:>>> ALIGNMENTS = OrderedChoices( ... ('BAD', 10, 'bad'), ... ('NEUTRAL', 20, 'neutral'), ... ('CHAOTIC_GOOD', 30, 'chaotic good'), ... ('GOOD', 40, 'good'), ... )
>>> ALIGNMENTS.dict_class <class 'collections.OrderedDict'>
>>> ALIGNMENTS.constants OrderedDict([('BAD', ('BAD', 10, 'bad')), ('NEUTRAL', ('NEUTRAL', 20, 'neutral')), ('CHAOTIC_GOOD', ('CHAOTIC_GOOD', 30, 'chaotic good')), ('GOOD', ('GOOD', 40, 'good'))]) >>> ALIGNMENTS.values OrderedDict([(10, ('BAD', 10, 'bad')), (20, ('NEUTRAL', 20, 'neutral')), (30, ('CHAOTIC_GOOD', 30, 'chaotic good')), (40, ('GOOD', 40, 'good'))]) >>> ALIGNMENTS.displays OrderedDict([('bad', ('BAD', 10, 'bad')), ('neutral', ('NEUTRAL', 20, 'neutral')), ('chaotic good', ('CHAOTIC_GOOD', 30, 'chaotic good')), ('good', ('GOOD', 40, 'good'))])
-
class
extended_choices.choices.AutoDisplayChoices(*choices, **kwargs)[source]¶ Bases:
extended_choices.choices.OrderedChoicesSubclass of
OrderedChoicesthat will compose the display value based on the constant.To compose the display value, it will call a
display_transformfunction, that is defined as a class attribute but can be overridden by passing it to the constructor.Example
>>> ALIGNMENTS = AutoDisplayChoices( ... ('BAD', 10), ... ('NEUTRAL', 20), ... ('CHAOTIC_GOOD', 30, 'THE CHAOS'), ... ('GOOD', 40, {'additional': 'attributes'}), ... )
>>> ALIGNMENTS.BAD.display 'Bad' >>> ALIGNMENTS.NEUTRAL.choice_entry ('NEUTRAL', 20, 'Neutral') >>> ALIGNMENTS.CHAOTIC_GOOD.display 'THE CHAOS' >>> ALIGNMENTS.GOOD.choice_entry.additional 'attributes'
-
static
display_transform(const)¶
-
static
-
class
extended_choices.choices.AutoChoices(*choices, **kwargs)[source]¶ Bases:
extended_choices.choices.AutoDisplayChoicesSubclass of
AutoDisplayChoicesthat will also compose the value to be saved based on the constant.To compose the display value, it will call a
display_transformfunction, that is defined as a class attribute but can be overridden by passing it to the constructor.In this class, the
*choicesargument can simply be strings, or tuples with one element (or two to add additional attributes)Example
>>> ALIGNMENTS = AutoChoices( ... 'BAD', ... ('NEUTRAL', ), ... ('CHAOTIC_GOOD', 'chaos', 'THE CHAOS'), ... ('GOOD', None, 'Yeah', {'additional': 'attributes'}), ... )
>>> ALIGNMENTS.BAD.value 'bad' >>> ALIGNMENTS.BAD.display 'Bad' >>> ALIGNMENTS.NEUTRAL.choice_entry ('NEUTRAL', 'neutral', 'Neutral') >>> ALIGNMENTS.CHAOTIC_GOOD.value 'chaos' >>> ALIGNMENTS.CHAOTIC_GOOD.display 'THE CHAOS' >>> ALIGNMENTS.GOOD.value 'good' >>> ALIGNMENTS.GOOD.display 'Yeah' >>> ALIGNMENTS.GOOD.choice_entry.additional 'attributes'
-
add_choices(*choices, **kwargs)[source]¶ Disallow super method to thing the first argument is a subset name
-
static
value_transform(const)¶
-