Login

CommaSeparatedIntegerField with CheckboxSelectMultiple Widget

Author:
brendansellers
Posted:
December 10, 2012
Language:
Python
Version:
1.4
Score:
2 (after 2 ratings)

This snippet allows you to use the CommaSeparatedIntegerField to store a set of integers that correspond to a set of choices. There are a couple other snippets that proclaim to do this, but they either don't work with the django 1.4, or are more complex.

 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
72
73
74
75
76
77
78
79
80
81
82
83
84
from django.forms import MultipleChoiceField
from django.forms.widgets import CheckboxSelectMultiple


# Widget
class CSICheckboxSelectMultiple(CheckboxSelectMultiple):
    def value_from_datadict(self, data, files, name):
        # Return a string of comma separated integers since the database, and
        # field expect a string (not a list).
        return ','.join(data.getlist(name))

    def render(self, name, value, attrs=None, choices=()):
        # Convert comma separated integer string to a list, since the checkbox
        # rendering code expects a list (not a string)
        if value:
            value = value.split(',')
        return super(CSICheckboxSelectMultiple, self).render(
            name, value, attrs=attrs, choices=choices
        )


# Form field
class CSIMultipleChoiceField(MultipleChoiceField):
    widget = CSICheckboxSelectMultiple

    # Value is stored and retrieved as a string of comma separated
    # integers. We don't want to do processing to convert the value to
    # a list like the normal MultipleChoiceField does.
    def to_python(self, value):
        return value

    def validate(self, value):
        # If we have a value, then we know it is a string of comma separated
        # integers. To use the MultipleChoiceField validator, we first have
        # to convert the value to a list.
        if value:
            value = value.split(',')
        super(CSIMultipleChoiceField, self).validate(value)

##########
# Example
##########

# models.py
from django.db import models

CHOICE0 = 0
CHOICE1 = 1
CHOICE2 = 2
CHOICE3 = 3
MY_CHOICES = (
    (CHOICE0, 'Choice 0'),
    (CHOICE1, 'Choice 1'),
    (CHOICE2, 'Choice 2'),
    (CHOICE3, 'Choice 3'),
)


class MyModel(models.Model):
    my_csi_field = models.CommaSeparatedIntegerField(
        'comma separated ints', max_length=255, blank=True,
        default='',
        choices=MY_CHOICES
    )

# admin.py
from django.contrib import admin
from django import forms


class MyModelForm(forms.ModelForm):
    my_csi_field = CSIMultipleChoiceField(
        required=False,
    )

    class Meta:
        model = MyModel


class MyModelAdmin(admin.ModelAdmin):
    form = MyModelForm


admin.site.register(MyModel, MyModelAdmin)

More like this

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

Comments

Please login first before commenting.