Login

MultipleChoiceCommaField

Author:
rubic
Posted:
February 26, 2007
Language:
Python
Version:
Pre .96
Score:
4 (after 4 ratings)

MultipleChoiceCommaField - CheckboxSelectMultiple value sequence as a single string, comma-separated.

Since I frequently want to store multiple-selected choice items as a single field in the model, I found it convenient to write a custom field class. The code uses the comma as a separator, but it could be easily generalized to use any delimiter.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from django import newforms as forms
from django.newforms.widgets import CheckboxSelectMultiple
from django.utils.datastructures import MultiValueDict

CommaSep = ','

class SelectCommaWidget(CheckboxSelectMultiple):
    def value_from_datadict(self, data, name):
        if isinstance(data, MultiValueDict):
            return data.getlist(name)
        retval = data.get(name)
        if isinstance(retval, type('')):
            retval = retval.split(CommaSep)
        return retval

class MultipleChoiceCommaField(forms.MultipleChoiceField):
    """
    MultipleChoiceCommaField will return the value sequence as a
    single string, comma-separated.  This could easily generalized
    to a use a specified delimiter other than the comma.

    >>> Choices = (('1','almonds'), ('2','pecans'), ('3','cashews'), ('4','walnuts'), ('5','peanuts'))
    >>> class NutForm(forms.Form):
    ...     nuts = MultipleChoiceCommaField(required=False, choices=Choices)
    ...

    >>> print NutForm({})
    <tr><th><label for="id_nuts_0">Nuts:</label></th><td><ul>
    <li><label><input type="checkbox" name="nuts" value="1" id="id_nuts_0" /> almonds</label></li>
    <li><label><input type="checkbox" name="nuts" value="2" id="id_nuts_1" /> pecans</label></li>
    <li><label><input type="checkbox" name="nuts" value="3" id="id_nuts_2" /> cashews</label></li>
    <li><label><input type="checkbox" name="nuts" value="4" id="id_nuts_3" /> walnuts</label></li>
    <li><label><input type="checkbox" name="nuts" value="5" id="id_nuts_4" /> peanuts</label></li>
    </ul></td></tr>
    
    >>> print NutForm({'nuts':'3'})
    <tr><th><label for="id_nuts_0">Nuts:</label></th><td><ul>
    <li><label><input type="checkbox" name="nuts" value="1" id="id_nuts_0" /> almonds</label></li>
    <li><label><input type="checkbox" name="nuts" value="2" id="id_nuts_1" /> pecans</label></li>
    <li><label><input checked="checked" type="checkbox" name="nuts" value="3" id="id_nuts_2" /> cashews</label></li>
    <li><label><input type="checkbox" name="nuts" value="4" id="id_nuts_3" /> walnuts</label></li>
    <li><label><input type="checkbox" name="nuts" value="5" id="id_nuts_4" /> peanuts</label></li>
    </ul></td></tr>
    
    >>> print NutForm({'nuts':'2,4'})
    <tr><th><label for="id_nuts_0">Nuts:</label></th><td><ul>
    <li><label><input type="checkbox" name="nuts" value="1" id="id_nuts_0" /> almonds</label></li>
    <li><label><input checked="checked" type="checkbox" name="nuts" value="2" id="id_nuts_1" /> pecans</label></li>
    <li><label><input type="checkbox" name="nuts" value="3" id="id_nuts_2" /> cashews</label></li>
    <li><label><input checked="checked" type="checkbox" name="nuts" value="4" id="id_nuts_3" /> walnuts</label></li>
    <li><label><input type="checkbox" name="nuts" value="5" id="id_nuts_4" /> peanuts</label></li>
    </ul></td></tr>
    >>> 
    """
    def __init__(self, **kwargs):
        if not 'widget' in kwargs:
            kwargs['widget'] = SelectCommaWidget
        super(forms.MultipleChoiceField, self).__init__(**kwargs)
    def clean(self, value):
        # The following lines are here to work around ticket #3482.  When the
        # ticket is fixed uncomment the next line and remove the remainder.
        #return CommaSep.join(super(MultipleChoiceCommaField, self).clean(value))
        v = super(MultipleChoiceCommaField, self).clean(value)
        if v == ['']:
            return []
        else:
            return CommaSep.join(v)

if __name__ == '__main__':
    import doctest
    doctest.testmod()

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

Please login first before commenting.