Skip to content

Instantly share code, notes, and snippets.

@mixxorz
Created August 22, 2016 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mixxorz/12dc7696bc5f18f6d1d9a7cc36fca85f to your computer and use it in GitHub Desktop.
Save mixxorz/12dc7696bc5f18f6d1d9a7cc36fca85f to your computer and use it in GitHub Desktop.
MultipleSelectField Django 1.10 Python 3.4
from django import forms
from django.core import exceptions
from django.db import models
from django.utils.encoding import force_text
class MultipleSelectFormField(forms.MultipleChoiceField):
widget = forms.CheckboxSelectMultiple
class MultipleSelectField(models.Field):
def get_internal_type(self):
return 'CharField'
def get_choices_default(self):
return self.get_choices(include_blank=False)
def formfield(self, **kwargs):
# don't call super, as that overrides default widget if it has choices
defaults = {
'required': not self.blank,
'label': self.verbose_name.capitalize(),
'help_text': self.help_text,
'choices': self.choices
}
if self.has_default():
defaults['initial'] = self.get_default()
defaults.update(kwargs)
return MultipleSelectFormField(**defaults)
def get_db_prep_value(self, value, connection, prepared=False):
if isinstance(value, list):
return ','.join(map(str, value))
if value is None or isinstance(value, str):
return value
else:
return str(value)
def from_db_value(self, value, expression, connection, context):
return str(value).split(',')
def to_python(self, value):
if value is None or isinstance(value, list):
return value
else:
return str(value).split(',')
def validate(self, value, model_instance):
if not self.editable:
# Skip validation for non-editable fields.
return
if self.choices and value not in self.empty_values:
if not isinstance(value, list):
value = [value]
if set(dict(self.choices).keys()) & set(value) == set(value):
return
raise exceptions.ValidationError(
self.error_messages['invalid_choice'],
code='invalid_choice',
params={'value': value},
)
if value is None and not self.null:
raise exceptions.ValidationError(
self.error_messages['null'], code='null')
if not self.blank and value in self.empty_values:
raise exceptions.ValidationError(
self.error_messages['blank'], code='blank')
def contribute_to_class(self, cls, name, virtual_only=False):
super(MultipleSelectField, self).contribute_to_class(cls, name)
if self.choices:
fieldname = self.name
choicedict = dict(self.choices)
def func(self):
value = getattr(self, fieldname)
if not isinstance(value, list):
value = [value]
return ', '.join([force_text(choicedict.get(i, i))
for i in value])
setattr(cls, 'get_%s_display' % fieldname, func)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment