Coverage for audoma/choices.py: 69%
16 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-04 07:22 +0000
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-04 07:22 +0000
1from typing import (
2 Any,
3 List,
4 Tuple,
5 TypeVar,
6)
9_T = TypeVar("_T")
12def make_choices(name: str, choices_tuple: Tuple[Any, str, str]) -> _T:
13 from collections import namedtuple
15 """Factory function for quickly making a namedtuple suitable for use in a
16 Django model as a choices attribute on a field. It will preserve order.
18 Usage::
20 class MyModel(models.Model):
21 COLORS = make_choices('COLORS', (
22 (0, 'BLACK', 'Black'),
23 (1, 'WHITE', 'White'),
24 ))
25 colors = models.PositiveIntegerField(choices=COLORS)
27 >>> MyModel.COLORS.BLACK
28 0
29 >>> MyModel.COLORS.get_choices()
30 [(0, 'Black'), (1, 'White')]
32 class OtherModel(models.Model):
33 GRADES = make_choices('GRADES', (
34 ('FR', 'FR', 'Freshman'),
35 ('SR', 'SR', 'Senior'),
36 ))
37 grade = models.CharField(max_length=2, choices=GRADES)
39 >>> OtherModel.GRADES.FR
40 'FR'
41 >>> OtherModel.GRADES.get_choices()
42 [('FR', 'Freshman'), ('SR', 'Senior')]
44 """
46 class Choices(namedtuple(name, [name_ for val, name_, desc in choices_tuple])):
47 __slots__ = ()
48 _choices = tuple([desc for val, name_, desc in choices_tuple])
50 def get_display(self, val: Any) -> str:
51 return self._choices[self.index(val)]
53 def get_choices(self) -> List[Tuple[Any, str]]:
54 return list(zip(tuple(self), self._choices))
56 def get_api_choices(self) -> List[Tuple[str, str]]:
57 return list(zip(tuple(self._asdict()), tuple(self._choices)))
59 def get_value_by_name(self, name: str) -> Any:
60 return getattr(self, name)
62 return Choices._make([val for val, name_, desc in choices_tuple])