This field provides a multi select choice field.
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 | # -*- coding: utf-8 -*-
from django import forms
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.encoding import force_unicode
from django.utils.text import capfirst
class MultiSelectField(models.TextField):
__metaclass__ = models.SubfieldBase
def get_db_prep_value(self, value):
if isinstance(value, basestring):
return value
elif isinstance(value, list):
return ','.join(value)
return ''
def to_python(self, value):
if isinstance(value, basestring):
return value.split(',')
elif isinstance(value, list):
return value
return ''
def value_to_string(self, obj):
# We need this to proper dump data.
return self.get_db_prep_value(self._get_val_from_obj(obj))
def get_choices_default(self):
return self.get_choices(include_blank=False)
def formfield(self, form_class=forms.MultipleChoiceField, **kwargs):
# Using super() won't work because this would replace the form_class.
defaults = {
'required': not self.blank,
'label': capfirst(self.verbose_name),
'help_text': self.help_text,
'choices': self.get_choices(include_blank=False),
}
if self.has_default():
if callable(self.default):
defaults['initial'] = self.default
defaults['show_hidden_initial'] = True
else:
defaults['initial'] = self.get_default()
defaults.update(kwargs)
return form_class(**defaults)
def validate(self, value, model_instance):
if isinstance(value, list):
valid_choices = [k for k, v in self.choices]
for choice in value:
if choice not in valid_choices:
raise ValidationError(
self.error_messages['invalid_choice'] % choice)
def _get_display(field):
def _inner(self):
values = getattr(self, field.attname)
return ', '.join([force_unicode(
field.choices_dict.get(value, value),
strings_only=True
) for value in values])
return _inner
def contribute_to_class(self, cls, name):
self.set_attributes_from_name(name)
self.model = cls
cls._meta.add_field(self)
self.choices_dict = dict(self.choices)
setattr(cls, 'get_%s_display' % self.name, self._get_display())
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.