Skip to content

Instantly share code, notes, and snippets.

@jbaldivieso
Created February 12, 2016 23:12
Show Gist options
  • Save jbaldivieso/96af08a6e0d55d634d4b to your computer and use it in GitHub Desktop.
Save jbaldivieso/96af08a6e0d55d634d4b to your computer and use it in GitHub Desktop.
Django code to make a multi-checkbox widget that works with Django's Postgres-based ArrayField
from django import forms
from django.forms import widgets
DELIMITER = ','
class MultiCheckboxChoiceInput(widgets.CheckboxChoiceInput):
def __init__(self, *args, **kwargs):
# yes, we *do* want the super class's super class --
# widgets.CheckboxChoiceInput's __init__ would take our comma-delimited
# string and turn it into a set of individual characters.
super(widgets.CheckboxChoiceInput, self).__init__(*args, **kwargs)
def is_checked(self):
# We're counting on alignment btw this class's delimiter and
# ArrayFieldCheckboxSelectMultiple's -- not ideal
values = set(self.value.split(DELIMITER))
return self.choice_value in values
class CheckboxFieldRenderer(widgets.ChoiceFieldRenderer):
choice_input_class = MultiCheckboxChoiceInput
class ArrayFieldCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
"""This is a Form Widget for use with a Postgres ArrayField. It implements
a multi-select interface that can be given a set of `choices`.
Derived from https://bradmontgomery.net/blog/nice-arrayfield-widgets-choices-and-chosenjs/
"""
renderer = CheckboxFieldRenderer
def render_options(self, choices, value):
# value *should* be a list, but it might be a delimited string.
if isinstance(value, str):
value = value.split(DELIMITER)
return super(ArrayFieldCheckboxSelectMultiple, self).render_options(
choices, value)
def value_from_datadict(self, data, files, name):
# Normally, we'd want a list here, which is what we get from the
# CheckboxSelectMultiple superclass, but the SimpleArrayField expects
# to get a delimited string, so we're doing a little extra work.
return DELIMITER.join(data.getlist(name))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment