Commits

Mark Lavin committed 73143a1 Merge

Merge back stable changes.

Comments (0)

Files changed (7)

 `Read The Docs <http://readthedocs.org/>`_:
 
 - `Dev <http://readthedocs.org/docs/django-selectable/en/latest/>`_
-- `v0.4.0 <http://readthedocs.org/docs/django-selectable/en/version-0.4.0/>`_
+- `v0.4.1 <http://readthedocs.org/docs/django-selectable/en/version-0.4.1/>`_
 - `v0.3.1 <http://readthedocs.org/docs/django-selectable/en/version-0.3.1/>`_
 - `v0.2.0 <http://readthedocs.org/docs/django-selectable/en/version-0.2.0/>`_
 - `v0.1.2 <http://readthedocs.org/docs/django-selectable/en/version-0.1.2/>`_
 # The short X.Y version.
 version = '0.4'
 # The full version, including alpha/beta/rc tags.
-release = '0.4.0'
+release = '0.4.1'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.

docs/releases.rst

 Release Notes
 ==================
 
+v0.4.1 (Released 2012-03-11)
+--------------------------------------
+
+Bug Fixes
+_________________
+
+- Cleaned up whitespace in css/js. Thanks Dan Poirier for the report and fix.
+- Fixed issue with saving M2M field data with AutoCompleteSelectMultipleField. Thanks Raoul Thill for the report.
+
+
 v0.4.0 (Released 2012-02-25)
 --------------------------------------
 

selectable/__init__.py

 __version_info__ = {
     'major': 0,
     'minor': 4,
-    'micro': 0,
+    'micro': 1,
     'releaselevel': 'final',
 }
 

selectable/forms/fields.py

 
     def to_python(self, value):
         if value in EMPTY_VALUES:
-            return None
+            return []
         lookup = self.lookup_class()
         items = []
         for v in value:

selectable/tests/__init__.py

         return self.name
 
 
+class ManyThing(models.Model):
+    name = models.CharField(max_length=100)
+    things = models.ManyToManyField(Thing)
+
+    def __unicode__(self):
+        return self.name
+
+
 class ThingLookup(ModelLookup):
     model = Thing
     search_fields = ('name__icontains', )

selectable/tests/functests.py

 
 from django import forms
 
-from selectable.forms import AutoCompleteSelectField
+from selectable.forms import AutoCompleteSelectField, AutoCompleteSelectMultipleField
 from selectable.forms import AutoCompleteSelectWidget, AutoComboboxSelectWidget
-from selectable.tests import OtherThing, ThingLookup
+from selectable.tests import ManyThing, OtherThing, ThingLookup
 from selectable.tests.base import BaseSelectableTestCase
 
 
     'FuncAutoCompleteSelectTestCase',
     'FuncSelectModelChoiceTestCase',
     'FuncComboboxModelChoiceTestCase',
+    'FuncManytoManyMultipleSelectTestCase',
 )
 
 
         }
         form = ComboboxSelectWidgetForm(data=data)
         self.assertTrue(form.is_valid(), str(form.errors))
+
+
+class ManyThingForm(forms.ModelForm):
+
+    things = AutoCompleteSelectMultipleField(lookup_class=ThingLookup)
+
+    class Meta(object):
+        model = ManyThing
+
+
+class FuncManytoManyMultipleSelectTestCase(BaseSelectableTestCase):
+    """
+    Functional tests for AutoCompleteSelectMultipleField compatibility
+    with a ManyToManyField.
+    """
+
+    def setUp(self):
+        self.test_thing = self.create_thing()
+
+    def test_valid_form(self):
+        "Valid form using an AutoCompleteSelectMultipleField."
+        data = {
+            'name': self.get_random_string(),
+            'things_0': u'', # Text input
+            'things_1': [self.test_thing.pk, ], # Hidden inputs
+        }
+        form = ManyThingForm(data=data)
+        self.assertTrue(form.is_valid(), str(form.errors))
+
+    def test_valid_save(self):
+        "Saving data from a valid form."
+        data = {
+            'name': self.get_random_string(),
+            'things_0': u'', # Text input
+            'things_1': [self.test_thing.pk, ], # Hidden inputs
+        }
+        form = ManyThingForm(data=data)
+        manything = form.save()
+        self.assertEqual(manything.name, data['name'])
+        things = manything.things.all()
+        self.assertEqual(things.count(), 1)
+        self.assertTrue(self.test_thing in things)
+
+    def test_not_required(self):
+        "Valid form where many to many is not required."
+        data = {
+            'name': self.get_random_string(),
+            'things_0': u'', # Text input
+            'things_1': [], # Hidden inputs
+        }
+        form = ManyThingForm(data=data)
+        form.fields['things'].required = False
+        self.assertTrue(form.is_valid(), str(form.errors))
+
+    def test_not_required_save(self):
+        "Saving data when many to many is not required."
+        data = {
+            'name': self.get_random_string(),
+            'things_0': u'', # Text input
+            'things_1': [], # Hidden inputs
+        }
+        form = ManyThingForm(data=data)
+        form.fields['things'].required = False
+        manything = form.save()
+        self.assertEqual(manything.name, data['name'])
+        things = manything.things.all()
+        self.assertEqual(things.count(), 0)