Skip to content

Instantly share code, notes, and snippets.

@mixxorz mixxorz/fields.py
Created Aug 22, 2016

Embed
What would you like to do?
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
You can’t perform that action at this time.