choices.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. class ChoiceSetMeta(type):
  2. """
  3. Metaclass for ChoiceSet
  4. """
  5. def __call__(cls, *args, **kwargs):
  6. # Django will check if a 'choices' value is callable, and if so assume that it returns an iterable
  7. return getattr(cls, 'CHOICES', ())
  8. def __iter__(cls):
  9. choices = getattr(cls, 'CHOICES', ())
  10. return iter(choices)
  11. class ChoiceSet(metaclass=ChoiceSetMeta):
  12. CHOICES = list()
  13. LEGACY_MAP = dict()
  14. @classmethod
  15. def values(cls):
  16. return [c[0] for c in unpack_grouped_choices(cls.CHOICES)]
  17. @classmethod
  18. def as_dict(cls):
  19. # Unpack grouped choices before casting as a dict
  20. return dict(unpack_grouped_choices(cls.CHOICES))
  21. @classmethod
  22. def slug_to_id(cls, slug):
  23. """
  24. Return the legacy integer value corresponding to a slug.
  25. """
  26. return cls.LEGACY_MAP.get(slug)
  27. @classmethod
  28. def id_to_slug(cls, legacy_id):
  29. """
  30. Return the slug value corresponding to a legacy integer value.
  31. """
  32. if legacy_id in cls.LEGACY_MAP.values():
  33. # Invert the legacy map to allow lookup by integer
  34. legacy_map = dict([
  35. (id, slug) for slug, id in cls.LEGACY_MAP.items()
  36. ])
  37. return legacy_map.get(legacy_id)
  38. def unpack_grouped_choices(choices):
  39. """
  40. Unpack a grouped choices hierarchy into a flat list of two-tuples. For example:
  41. choices = (
  42. ('Foo', (
  43. (1, 'A'),
  44. (2, 'B')
  45. )),
  46. ('Bar', (
  47. (3, 'C'),
  48. (4, 'D')
  49. ))
  50. )
  51. becomes:
  52. choices = (
  53. (1, 'A'),
  54. (2, 'B'),
  55. (3, 'C'),
  56. (4, 'D')
  57. )
  58. """
  59. unpacked_choices = []
  60. for key, value in choices:
  61. if isinstance(value, (list, tuple)):
  62. # Entered an optgroup
  63. for optgroup_key, optgroup_value in value:
  64. unpacked_choices.append((optgroup_key, optgroup_value))
  65. else:
  66. unpacked_choices.append((key, value))
  67. return unpacked_choices
  68. #
  69. # Button color choices
  70. #
  71. class ButtonColorChoices(ChoiceSet):
  72. """
  73. Map standard button color choices to Bootstrap color classes
  74. """
  75. DEFAULT = 'default'
  76. BLUE = 'primary'
  77. GREY = 'secondary'
  78. GREEN = 'success'
  79. RED = 'danger'
  80. YELLOW = 'warning'
  81. BLACK = 'dark'
  82. CHOICES = (
  83. (DEFAULT, 'Default'),
  84. (BLUE, 'Blue'),
  85. (GREY, 'Grey'),
  86. (GREEN, 'Green'),
  87. (RED, 'Red'),
  88. (YELLOW, 'Yellow'),
  89. (BLACK, 'Black')
  90. )