Select multiple choices in a single Django model field. Use whenever you want to store multiple choices in a field without using a many-to-many relation.
Rendered using the multiselect.js plugin for jQuery [1]
| [1] | jquery.multi-select.js https://github.com/lou/multi-select |
Important
Field attribute max_length must be set to a value longer than your
longest expected encoded string
Important
Choices must be strings, not integers.
In your models add the select field choices normally:
# models.py
class Pizza(models.Model):
ANCHOVIES = 'a'
BLACK_OLIVES = 'b'
PEPPERONI = 'p'
MOZZARELLA = 'm'
TOPPING_CHOICES = (
(ANCHOVIES, 'Anchovies'),
(BLACK_OLIVES, 'Black olives'),
(PEPPERONI, 'Pepperoni'),
(MOZZARELLA, 'Mozzarella'),
)
toppings = SelectMultipleField(
max_length=10,
choices=TOPPING_CHOICES
)
Use a generic view or a modelform as usual. In your template you can use a regular form tag:
# template_form.html
<form action="" method="post">
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
This renders the following HTML:
# create.html
<form action="" method="post">
<p>
<label for="id_toppings">Toppings:</label>
<select multiple="multiple" id="id_toppings" name="toppings"
class="select-multiple-field">
<option value="a">Anchovies</option>
<option value="b">Black olives</option>
<option value="p">Pepperoni</option>
<option value="m">Mozzarella</option>
</select>
</p>
<input type="submit" value="Submit">
</form>
To display your choices, you will need to decode the field contents. This can be accomplished with a template tag:
# templatetags/pizza_tags.py
def decode_pie(ingredients):
"""
Decode pizza pie toppings
"""
decoder = dict(Pizza.TOPPING_CHOICES)
decoded = [decoder[t] for t in ingredients]
decoded.sort()
return ', '.join(decoded)
register.filter('decode_pie', decode_pie)
In your template you need to import your tags and use them:
# details.html
{% load pizza_tags %}
{{ pizza.toppings|decode_pie }}
The choices that are selected are stored as comma-delimited text. Consider a pizza with the following toppings.
- Pepperoni
- Mozzarella
This would be stored as a character field as:
p,m
This encoded string is decoded to a Python list using functions in the codecs module:
>>> from select_multiple_field.codecs import * >>> encoded = 'a,b,c' >>> decoded = decode_csv_to_list(encoded) >>> print decoded [u'a', u'b', u'c'] >>> print type(decoded) <type 'list'>
The method of encoding may limit your ability to search for choices.
There is a sample application included if you downloaded the tarball. You can try it like this:
$ pwd /home/user/teststuff/django-select-multiple-field $ cd test_projects/django14 $ python manage.py syncdb $ python manage.py runserver Validating models... 0 errors found Django version 1.4.19, using settings 'django14.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
Django-select-multiple-field contains two test suites. One is for the field and one is for an implementation of the field in a Django 1.4.19 project.
You can run the field tests by downloading the tarball and running 'test' in setup.py:
$ python setup.py test
You can run the Django 1.4.19 demo test in a similar manner:
$ python setup.py test_demo
Needless to say you will need to have Django 1.4.19 or later installed.
If you find any bugs in this software please report them via the Github issue tracker [2] or send an email to code@kelvinwong.ca. Any serious security bugs should be reported via email only.
| [2] | Django-select-multiple-field issue tracker https://github.com/kelvinwong-ca/django-select-multiple-field/issues |
- https://pypi.python.org/pypi/django-select-multiple-field/
- https://github.com/kelvinwong-ca/django-select-multiple-field
Thank-you for taking the time to evaluate this software. I appreciate receiving feedback on your experiences using it and I welcome code contributions and development ideas.