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)