Add filter_choices helper function.
[matthijs/projects/xerxes.git] / tools / misc.py
1 """
2 Makes an iteratable object out of the given value. If value is already
3 iterable, it is simply returned. An exception is made for strings, which
4 are treated as non-iterable (It is assumed that you never want to have a
5 list of characters). For non iteratable values or strings, a list
6 containing only value is returned.
7 """
8 def make_iter(value):
9     if (not isinstance(value, basestring)):
10         try:
11             iter(value)
12             return value
13         except TypeError:
14             pass
15     return [value]
16 # vim: set sts=4 sw=4 expandtab:
17
18 """
19 Decarator that catches any exception raised by the decorated function,
20 prints it to stdout and raises it again.
21 """
22 def log_error(func):
23     def show(*args, **kwargs):
24         try:
25             return func(*args, **kwargs)
26         except Exception, e:
27             import traceback
28             traceback.print_exc()
29             raise e
30     return show
31
32 def make_choices(objects):
33     """
34     Transforms a list (or iteratable) of model objects to a list
35     suitable to be used as a list of choices in form widgets like
36     Select.
37
38     This fullfills a similar (but simpler) function as
39     django.forms.models.ModelChoiceIterator, but that one requires a
40     FormField and is not public.
41     """
42     return [(o.pk, o) for o in objects]
43
44 def filter_choices(choices, filter):
45     """
46     Returns the given choices list with only the choices with the names
47     in filter left. For example, when a model defines
48     A   = 'A'
49     B   = 'B'
50     FOO_CHOICES = (
51         (A, "Foo A"),
52         (B, "Foo B")
53     )
54
55     you can later define a modelfield using
56
57     foo = ChoiceField(choices=filter_choices(Foo.FOO_CHOICES, [Foo.A]))
58     """
59     return [(name, value) for (name, value) in choices if name in filter]