Add tests for named groups

This commit is contained in:
Drew Hubl 2016-09-23 05:55:08 -06:00
parent 203411c3cf
commit 95a47c7d22
5 changed files with 85 additions and 57 deletions

View file

@ -7,45 +7,45 @@ python:
- "3.4"
- "3.5"
env:
- DJANGO=1.4
- DJANGO=1.5
- DJANGO=1.6
- DJANGO=1.7
- DJANGO=1.8
- DJANGO=1.9
- DJANGO=1.10
- DJANGO=1.4.22
- DJANGO=1.5.12
- DJANGO=1.6.11
- DJANGO=1.7.11
- DJANGO=1.8.14
- DJANGO=1.9.9
- DJANGO=1.10.1
matrix:
exclude:
- python: "2.6"
env: DJANGO=1.7
env: DJANGO=1.7.11
- python: "2.6"
env: DJANGO=1.8
env: DJANGO=1.8.14
- python: "2.6"
env: DJANGO=1.9
env: DJANGO=1.9.9
- python: "2.6"
env: DJANGO=1.10
env: DJANGO=1.10.1
- python: "3.3"
env: DJANGO=1.4
env: DJANGO=1.4.22
- python: "3.4"
env: DJANGO=1.4
env: DJANGO=1.4.22
- python: "3.5"
env: DJANGO=1.4
env: DJANGO=1.4.22
- python: "3.3"
env: DJANGO=1.5
env: DJANGO=1.5.12
- python: "3.4"
env: DJANGO=1.5
env: DJANGO=1.5.12
- python: "3.5"
env: DJANGO=1.5
env: DJANGO=1.5.12
- python: "3.4"
env: DJANGO=1.6
env: DJANGO=1.6.11
- python: "3.5"
env: DJANGO=1.6
env: DJANGO=1.6.11
- python: "3.5"
env: DJANGO=1.7
env: DJANGO=1.7.11
- python: "3.3"
env: DJANGO=1.9
env: DJANGO=1.9.9
- python: "3.3"
env: DJANGO=1.10
env: DJANGO=1.10.1
install:
- pip install -q Django==$DJANGO

View file

@ -17,6 +17,10 @@ A new model field and form field. With this you can get a multiple select from a
This egg is inspired by this `snippet <http://djangosnippets.org/snippets/1200/>`_.
Supported Python versions: 2.6, 2.7, 3.3+
Supported Django versions: 1.4-1.0+
Installation
============
@ -75,11 +79,15 @@ Only you need it, if you want the translation of django-multiselectfield
Known Bugs and Limitations
==========================
Only in Django 1.6 and 1.7, due to `Django bug #9619 <https://code.djangoproject.com/ticket/9619>`_, passing a MultiSelectField to ``values()`` or ``values_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.
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:
The Django bug was introduced in Django 1.6 and is fixed in Django 1.8 and onward, so ``values()`` and ``values_list()`` return a vanilla Python list of values for Django <= 1.5 and Django >= 1.8.
1. `Named groups <https://github.com/goinnn/django-multiselectfield/pull/30#issue-52149983>`_ 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.
See `issue #40 <https://github.com/goinnn/django-multiselectfield/issues/40>`_ for discussion about this bug.
2. Only in Django 1.6 and 1.7, due to `Django bug #9619 <https://code.djangoproject.com/ticket/9619>`_, passing a MultiSelectField to ``values()`` or ``values_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()`` and ``values_list()`` return a vanilla Python list of values for Django <= 1.5 and Django >= 1.8.
See `issue #40 <https://github.com/goinnn/django-multiselectfield/issues/40>`_ for discussion about this bug.
Development
@ -96,11 +104,10 @@ of its git repository:
Example project
===============
In the source tree, you will find a directory called `example <https://github.com/goinnn/django-multiselectfield/tree/master/example/>`_. It contains
a readily setup project that uses django-multiselectfield. You can run it as usual:
There is a fully configured example project in the `example directory <https://github.com/goinnn/django-multiselectfield/tree/master/example/>`_. You can run it as usual:
.. code-block:: bash
python manage.py syncdb --noinput
python manage.py migrate # or python manage.py syncdb --noinput
python manage.py loaddata app_data
python manage.py runserver

View file

@ -20,11 +20,11 @@ from django.utils.translation import gettext as _
from multiselectfield import MultiSelectField
CATEGORY_CHOICES = (
(1, 'Handbooks and manuals by discipline'),
(2, 'Business books'),
(3, 'Books of literary criticism'),
(4, 'Books about literary theory'),
(5, 'Books about literature')
(1, _('Handbooks and manuals by discipline')),
(2, _('Business books')),
(3, _('Books of literary criticism')),
(4, _('Books about literary theory')),
(5, _('Books about literature')),
)
TAGS_CHOICES = (
@ -64,7 +64,9 @@ class Book(models.Model):
default=1)
tags = MultiSelectField(choices=TAGS_CHOICES,
null=True, blank=True)
published_in = MultiSelectField(_("Province or State"), max_length=2, choices=PROVINCES_AND_STATES)
published_in = MultiSelectField(_("Province or State"),
choices=PROVINCES_AND_STATES,
max_choices=2)
def __str__(self):
return self.title

View file

@ -23,7 +23,7 @@ from django.test import TestCase
from multiselectfield.utils import get_max_length
from .models import Book, PROVINCES, STATES
from .models import Book, PROVINCES, STATES, PROVINCES_AND_STATES
if sys.version_info < (3,):
@ -43,6 +43,7 @@ else:
class MultiSelectTestCase(TestCase):
fixtures = ['app_data.json']
maxDiff = 4000
def assertListEqual(self, left, right, msg=None):
if sys.version_info >= (3, 2):
@ -128,10 +129,28 @@ class MultiSelectTestCase(TestCase):
self.assertEqual(get_field(Book, 'categories').value_to_string(book), '1,3,5')
def test_flatchoices(self):
#raise Exception(Book._meta.get_field('published_in').flatchoices)
# raise Exception(Book.published_in.flatchoices)
self.assertEqual(get_field(Book, 'published_in').flatchoices, list(PROVINCES+STATES))
def test_named_groups(self):
self.assertEqual(get_field(Book, 'published_in').choices, PROVINCES_AND_STATES)
def test_named_groups_form(self):
form_class = modelform_factory(Book, fields=('published_in',))
self.assertEqual(len(form_class.base_fields), 1)
form = form_class(initial={'published_in': ['BC', 'AK']})
expected_html = u("""<p><label for="id_published_in_0">Province or State:</label> <ul id="id_published_in"><li>Canada - Provinces<ul id="id_published_in_0"><li><label for="id_published_in_0_0"><input id="id_published_in_0_0" name="published_in" type="checkbox" value="AB" /> Alberta</label></li>\n"""
"""<li><label for="id_published_in_0_1"><input checked="checked" id="id_published_in_0_1" name="published_in" type="checkbox" value="BC" /> British Columbia</label></li></ul></li>\n"""
"""<li>USA - States<ul id="id_published_in_1"><li><label for="id_published_in_1_0"><input checked="checked" id="id_published_in_1_0" name="published_in" type="checkbox" value="AK" /> Alaska</label></li>\n"""
"""<li><label for="id_published_in_1_1"><input id="id_published_in_1_1" name="published_in" type="checkbox" value="AL" /> Alabama</label></li>\n"""
"""<li><label for="id_published_in_1_2"><input id="id_published_in_1_2" name="published_in" type="checkbox" value="AZ" /> Arizona</label></li></ul></li></ul></p>""")
actual_html = form.as_p()
if VERSION < (1, 6) or VERSION >= (1, 7):
# Django 1.6 renders the Python repr() for each group (eg: tuples
# with HTML entities), so we skip the test for that version
self.assertEqual(expected_html.replace('\n', ''), actual_html.replace('\n', ''))
class MultiSelectUtilsTestCase(TestCase):
def test_get_max_length_max_length_is_not_none(self):

40
tox.ini
View file

@ -14,7 +14,7 @@ install_command =
[testenv:py26-dj14]
basepython = python2.6
deps =
django==1.4.10
django==1.4.22
pillow==1.7.8
PyYAML==3.10
coveralls==0.3
@ -22,7 +22,7 @@ deps =
[testenv:py26-dj15]
basepython = python2.6
deps =
django==1.5.5
django==1.5.12
pillow==1.7.8
PyYAML==3.10
coveralls==0.3
@ -30,7 +30,7 @@ deps =
[testenv:py26-dj16]
basepython = python2.6
deps =
django==1.6
django==1.6.11
pillow==1.7.8
PyYAML==3.10
coveralls==0.3
@ -39,7 +39,7 @@ deps =
[testenv:py27-dj14]
basepython = python2.7
deps =
django==1.4.10
django==1.4.22
pillow==1.7.8
PyYAML==3.10
coveralls==0.3
@ -47,7 +47,7 @@ deps =
[testenv:py27-dj15]
basepython = python2.7
deps =
django==1.5.5
django==1.5.12
pillow==1.7.8
PyYAML==3.10
coveralls==0.3
@ -55,7 +55,7 @@ deps =
[testenv:py27-dj16]
basepython = python2.7
deps =
django==1.6
django==1.6.11
pillow==1.7.8
PyYAML==3.10
coveralls==0.3
@ -63,7 +63,7 @@ deps =
[testenv:py27-dj17]
basepython = python2.7
deps =
django==1.7
django==1.7.11
pillow==1.7.8
PyYAML==3.10
coveralls==0.3
@ -71,7 +71,7 @@ deps =
[testenv:py27-dj18]
basepython = python2.7
deps =
django==1.8
django==1.8.14
pillow==1.7.8
PyYAML==3.10
coveralls==0.3
@ -79,7 +79,7 @@ deps =
[testenv:py27-dj19]
basepython = python2.7
deps =
django==1.9
django==1.9.9
pillow==1.7.8
PyYAML==3.10
coveralls==0.3
@ -87,7 +87,7 @@ deps =
[testenv:py27-dj110]
basepython = python2.7
deps =
django==1.10
django==1.10.1
pillow==1.7.8
PyYAML==3.10
coveralls==0.3
@ -96,7 +96,7 @@ deps =
[testenv:py33-dj16]
basepython = python3.3
deps =
django==1.6
django==1.6.11
pillow==2.1.0
PyYAML==3.10
coveralls==0.3
@ -104,7 +104,7 @@ deps =
[testenv:py33-dj17]
basepython = python3.3
deps =
django==1.7
django==1.7.11
pillow==2.1.0
PyYAML==3.10
coveralls==0.3
@ -112,7 +112,7 @@ deps =
[testenv:py33-dj18]
basepython = python3.3
deps =
django==1.8
django==1.8.14
pillow==2.1.0
PyYAML==3.10
coveralls==0.3
@ -121,7 +121,7 @@ deps =
[testenv:py34-dj17]
basepython = python3.4
deps =
django==1.7
django==1.7.11
pillow==2.1.0
PyYAML==3.10
coveralls==0.3
@ -129,7 +129,7 @@ deps =
[testenv:py34-dj18]
basepython = python3.4
deps =
django==1.8
django==1.8.14
pillow==2.1.0
PyYAML==3.10
coveralls==0.3
@ -137,7 +137,7 @@ deps =
[testenv:py34-dj19]
basepython = python3.4
deps =
django==1.9
django==1.9.9
pillow==2.1.0
PyYAML==3.10
coveralls==0.3
@ -145,7 +145,7 @@ deps =
[testenv:py34-dj110]
basepython = python3.4
deps =
django==1.10
django==1.10.1
pillow==2.1.0
PyYAML==3.10
coveralls==0.3
@ -154,7 +154,7 @@ deps =
[testenv:py35-dj18]
basepython = python3.5
deps =
django==1.8
django==1.8.14
pillow==2.1.0
PyYAML==3.10
coveralls==0.3
@ -162,7 +162,7 @@ deps =
[testenv:py35-dj19]
basepython = python3.5
deps =
django==1.9
django==1.9.9
pillow==2.1.0
PyYAML==3.10
coveralls==0.3
@ -170,7 +170,7 @@ deps =
[testenv:py35-dj110]
basepython = python3.5
deps =
django==1.10
django==1.10.1
pillow==2.1.0
PyYAML==3.10
coveralls==0.3