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:
list
Helper class for choices fields in Django
A choice entry has three representation: constant name, value and display name). So
Choices
takes 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
Choices
instance, 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
ChoiceEntry
created 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
Choices
instance with many calls toadd_choices
. - dict_class (type, optional) –
dict
by default, it’s the dict class to use to create dictionaries (constants
,values
anddisplays
. Could be set for example toOrderedDict
(you can useOrderedChoices
that 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
choices
anddefault
:>>> 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
Choices
returns 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
choices
which 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
Choices
instance.The given choices will be added to the existing choices. If a
name
attribute 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
Choices
instance, 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
ChoiceEntry
created for this choice tuple.If the first entry of
*choices
is 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
*choices
to pass a name of a subset to create, you can pass it via thename
named 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
Choices
instance 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
Choices
instance, 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 mainChoices
by an attribute having the given name.Parameters: - name (string) – Name of the attribute that will old the new
Choices
instance. - constants (list or tuple) – List of the constants name of this
Choices
object to make available in the subset.
Returns: The newly created subset, which is a
Choices
objectReturn 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
name
is already an attribute of theChoices
instance. * If a constant is not defined as a constant in theChoices
instance.
- 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
Choices
instance, 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 Choices
object to make available in the subset.Returns: The newly created subset, which is a Choices
objectReturn 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 Choices
instance.
-
for_constant
(constant)[source]¶ Returns the
ChoiceEntry
for the given constant.Parameters: constant (string) – Name of the constant for which we want the choice entry. Returns: The instance of ChoiceEntry
for 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
ChoiceEntry
for the given display name.Parameters: display (string) – Display name for which we want the choice entry. Returns: The instance of ChoiceEntry
for 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
ChoiceEntry
for the given value.Parameters: value – Value for which we want the choice entry. Returns: The instance of ChoiceEntry
for 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
Choices
object has the given constant.Parameters: constant (string) – Name of the constant we want to check.. Returns: True
if the constant is present,False
otherwise.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
Choices
object has the given display name.Parameters: display (string) – Display name we want to check.. Returns: True
if the display name is present,False
otherwise.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
Choices
object has the given value.Parameters: value – Value we want to check. Returns: True
if the value is present,False
otherwise.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.Choices
Simple subclass of
Choices
usingOrderedDict
asdict_class
Example
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.OrderedChoices
Subclass of
OrderedChoices
that will compose the display value based on the constant.To compose the display value, it will call a
display_transform
function, 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.AutoDisplayChoices
Subclass of
AutoDisplayChoices
that will also compose the value to be saved based on the constant.To compose the display value, it will call a
display_transform
function, that is defined as a class attribute but can be overridden by passing it to the constructor.In this class, the
*choices
argument 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)¶
-