Coverage for audoma/choices.py: 69%

1 from typing import (

2 Any,

3 List,

4 Tuple,

5 TypeVar,

6)

7

8

9 _T = TypeVar("_T")

10

11

12 def make_choices(name: str, choices_tuple: Tuple[Any, str, str]) -> _T:

13 from collections import namedtuple

14

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.

17

18 Usage::

19

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)

26

27 >>> MyModel.COLORS.BLACK

28 0

29 >>> MyModel.COLORS.get_choices()

30 [(0, 'Black'), (1, 'White')]

31

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)

38

39 >>> OtherModel.GRADES.FR

40 'FR'

41 >>> OtherModel.GRADES.get_choices()

42 [('FR', 'Freshman'), ('SR', 'Senior')]

43

44 """

45

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])

49

50 def get_display(self, val: Any) -> str:

51 return self._choices[self.index(val)]

52

53 def get_choices(self) -> List[Tuple[Any, str]]:

54 return list(zip(tuple(self), self._choices))

55

56 def get_api_choices(self) -> List[Tuple[str, str]]:

57 return list(zip(tuple(self._asdict()), tuple(self._choices)))

58

59 def get_value_by_name(self, name: str) -> Any:

60 return getattr(self, name)

61

62 return Choices._make([val for val, name_, desc in choices_tuple])