A new model field and form field. With this you can get a multiple select from a choices. Stores to the database as a CharField of comma-separated values.
This egg is inspired by this snippet.
Supported Python versions: 2.7, 3.4+
Supported Django versions: 1.4-2.0+
$ pip install django-multiselectfield
from multiselectfield import MultiSelectField
# ...
MY_CHOICES = (('item_key1', 'Item title 1.1'),
('item_key2', 'Item title 1.2'),
('item_key3', 'Item title 1.3'),
('item_key4', 'Item title 1.4'),
('item_key5', 'Item title 1.5'))
MY_CHOICES2 = ((1, 'Item title 2.1'),
(2, 'Item title 2.2'),
(3, 'Item title 2.3'),
(4, 'Item title 2.4'),
(5, 'Item title 2.5'))
class MyModel(models.Model):
# .....
my_field = MultiSelectField(choices=MY_CHOICES)
my_field2 = MultiSelectField(choices=MY_CHOICES2,
max_choices=3,
max_length=3)
Only you need it, if you want the translation of django-multiselectfield
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
#.....................#
'multiselectfield',
)
It is possible to customize the HTML of this widget in your form template. To do so, you will need to loop through form.{field}.field.choices
. Here is an example that displays the field label underneath/after the checkbox for a MultiSelectField
called providers
:
{% for value, text in form.providers.field.choices %}
<div class="ui slider checkbox">
<input id="id_providers_{{ forloop.counter0 }}" name="{{ form.providers.name }}" type="checkbox" value="{{ value }}"{% if value in checked_providers %} checked="checked"{% endif %}>
<label>{{ text }}</label>
</div>
{% endfor %}
Django REST Framework comes with a MultipleChoiceField
that works perfectly with this:
from rest_framework import fields, serializers
from myapp.models import MY_CHOICES, MY_CHOICES2
class MyModelSerializer(serializers.HyperlinkedModelSerializer):
# ...
my_field = fields.MultipleChoiceField(choices=MY_CHOICES)
my_field2 = fields.MultipleChoiceField(choices=MY_CHOICES2)
# ...
All tests pass on Django 1.4, 1.5, and 1.8+, so if you can, use a modern version of Django. However, if you must use Django 1.6 or 1.7 there are two known issues you will need to be aware of:
Named groups do not render properly in Django 1.6. The workaround is to manually render the field in your form or use a custom widget. If your workaround is suitably generic, please submit a pull request with it.
Only in Django 1.6 and 1.7, due to Django bug #9619, passing a MultiSelectField to
values()
orvalues_list()
will return the database representation of the field (a string of comma-separated values). The workaround is to manually call.split(',')
on the result.The Django bug was introduced in Django 1.6 and is fixed in Django 1.8 and onward, so
values()
andvalues_list()
return a vanilla Python list of values for Django <= 1.5 and Django >= 1.8.See issue #40 for discussion about this bug.
You can get the last bleeding edge version of django-multiselectfield by doing a clone of its git repository:
git clone https://github.com/goinnn/django-multiselectfield
There is a fully configured example project in the example directory. You can run it as usual:
python manage.py migrate # or python manage.py syncdb --noinput
python manage.py loaddata app_data
python manage.py runserver